一個練習專案,好玩的bbs-python-bottle

河北大学-徐小波發表於2024-09-02

程式碼:

from bottle import route, run, template
from bottle import Bottle, request, response
import os.path
import MySQLdb
import json
import hashlib
import random
import math
import os
from datetime import datetime

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        else:
            return json.JSONEncoder.default(self, obj)

secretKey = 'saacac3423@21212'
pagesize = 20
app = Bottle()

def getConn():
    conn = MySQLdb.Connection('127.0.0.1', 'root', '123456', 'my_bbs')
    cursor = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
    return (conn, cursor)

def getloginuserinfo(sessionId):
    (conn, cursor) = getConn()
    try:
        sessionIdHead = request.cookies.get("sessionId")
    except:
        sessionIdHead = ''
    
    if sessionIdHead is not None and sessionIdHead != '':
        sessionId = sessionIdHead
        
    sql = "select id,username,nickname,addTime,sessionId from user where sessionId='%s'" % sessionId
    cursor.execute(sql)
    data = cursor.fetchone()
    if data is None:
        data = {'id' : 0, 'username' : '', 'nickname' : '', 'addTime' : '', 'sessionId' : ''}
    
    return data
    
def responsex(code, msg, data):
    if code != 0:
        result = {'code' : code, 'msg' : msg, 'data' : None}
    else:
        result = {'code' : 0, 'msg' : '', 'data' : data}
        
    result = json.dumps(result, cls = DateEncoder, ensure_ascii = False)
    response.set_header('Server', 'bottle-Web-Framework')
        
    return result

def error(code, msg):
    return responsex(code, msg, None)

def success( data = {}):
    return responsex(0, '', data)
    
@app.route('/')
def index():
    (conn, cursor) = getConn()
    result = "此站介面使用python.bottle實現,<a href='api.html' target='_blank'>介面列表</a>"
    response.set_header('Server', 'bottle-Web-Framework')
    
    return result

@app.route('/user/register')
def register():
    (conn, cursor) = getConn()
    username = request.query.username
    password = request.query.password
    nickname = request.query.nickname
    sql = "select id,username,nickname,addTime from user where username='%s'" % username
    cursor.execute(sql)
    data = cursor.fetchone()
    if data != None:
        return error(1, '使用者名稱已經存在')

    try:
        passwordMd5 = hashlib.md5(password.encode(encoding='utf-8')).hexdigest()
        sql = "insert into user(username, password, nickname) value('%s', '%s', '%s')" % (username, passwordMd5, nickname)
        cursor.execute(sql)
        conn.commit()
        insertId = cursor.lastrowid
        return success(insertId)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '註冊失敗')

@app.route('/user/login')
def login():
    (conn, cursor) = getConn()
    username = request.query.username
    password = request.query.password
    passwordMd5 = hashlib.md5(password.encode(encoding='utf-8')).hexdigest()
    sql = "select id,username,nickname,addTime from user where username='%s' and password='%s'" % (username, passwordMd5)
    cursor.execute(sql)
    data = cursor.fetchone()
    if data == None:
        return error(1, '使用者名稱或者密碼錯誤')

    tmpSessionId = secretKey + str(data['id']) + str(data['addTime'])
    tmpSessionId = hashlib.md5(tmpSessionId.encode(encoding='utf-8')).hexdigest()
    try:
        sql = "update user set sessionId='%s' where id=%s" % (tmpSessionId, data['id'])
        cursor.execute(sql)
        conn.commit()
        data['sessionId'] = tmpSessionId
        return success(data)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '儲存會話id失敗')

@app.route('/user/logout')        
def logout():
    (conn, cursor) = getConn()
    sessionId = request.query.sessionId
    data = getloginuserinfo(sessionId)
    
    if data == None:
        return success(None)
    
    if data['sessionId'] == '':
        return success(data)

    try:
        sql = "update user set sessionId='' where sessionId='%s'" % sessionId
        cursor.execute(sql)
        conn.commit()
        data['sessionId'] = ''
        return success(data)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '刪除會話id失敗')

@app.route('/user/getuserinfo') 
def getuserinfo():
    (conn, cursor) = getConn()
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    return success(userinfo)
    
@app.route('/post/list')
def postlist():
    (conn, cursor) = getConn()
    page = request.query.page
    keyword = request.query.keyword
    if page == "":
        page = 1
    page = int(page)
    if page <= 0:
        page = 1
    addsql = " isDel=0 "
    if keyword is not None and keyword != '':
        addsql = " isDel=0 and title like '%"+keyword+"%' "
        
    start = (page - 1) * pagesize
    
    sql1 = "select count(1) as count from content where %s" % addsql
    cursor.execute(sql1)
    countdata = cursor.fetchone()
    totalpage = math.ceil(countdata['count'] / float(pagesize))
    
    data = []
    if totalpage > 0:
        sql2 = "select id,title,userId,userNickename,replyNum,updateTime from content where %s order by updateTime desc limit %s,%s" % (addsql, start, pagesize)
        cursor.execute(sql2)
        data = cursor.fetchall()
    
    return success({'totalpage' : totalpage, 'data' : data})

@app.route('/post/detail')
def postdetail():
    (conn, cursor) = getConn()
    id = request.query.id
    sql = "select id,title,content,userId,userNickename,replyNum,updateTime from content where isDel=0 and id=%s" % id
    cursor.execute(sql)
    data = cursor.fetchone()
    
    return success(data)

@app.route('/post/add')  
def postadd():
    (conn, cursor) = getConn()
    title = request.query.title
    content = request.query.content
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    try:
        sql = "insert into content(title, content, userId, userNickename) value('%s', '%s', %s, '%s')" % (title, content, userId, userNickename)
        cursor.execute(sql)
        conn.commit()
        insertId = cursor.lastrowid
        return success(insertId)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '發帖失敗')

@app.route('/post/edit') 
def postedit():
    (conn, cursor) = getConn()
    id = request.query.id
    title = request.query.title
    content = request.query.content
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    try:
        sql = "update content set title='%s',content='%s',userId=%s,userNickename='%s' where id=%s and userId=%s" % (title, content, userId, userNickename, id, userId)
        cursor.execute(sql)
        conn.commit()
        return success(None)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '編輯帖子失敗')

@app.route('/post/delete') 
def postdelete():
    (conn, cursor) = getConn()
    id = request.query.id
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    try:
        sql = "update content set isDel=1 where id=%s and userId=%s" % (id, userId)
        cursor.execute(sql)
        conn.commit()
        return success(None)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '刪除帖子失敗')
    
@app.route('/reply/list') 
def replylist():
    (conn, cursor) = getConn()
    page = request.query.page
    contentId = request.query.contentId
    if page == "":
        page = 1
    page = int(page)
    if page <= 0:
        page = 1
    start = (page - 1) * pagesize
    
    sql1 = "select count(1) as count from reply where isDel=0 and contentId=%s" % contentId
    cursor.execute(sql1)
    countdata = cursor.fetchone()
    totalpage = math.ceil(countdata['count'] / float(pagesize))
    
    data = []
    if totalpage > 0:
        sql2 = "select id,content,replyUserId,replyUserNickename,addTime from reply where isDel=0 and contentId=%s order by id asc limit %s,%s" % (contentId, start, pagesize)
        cursor.execute(sql2)
        data = cursor.fetchall()
    
    return success({'totalpage' : totalpage, 'data' : data})
    
@app.route('/reply/detail') 
def replydetail():
    (conn, cursor) = getConn()
    id = request.query.id
    sql = "select id,content,replyUserId,replyUserNickename,addTime from reply where isDel=0 and id=%s" % id
    cursor.execute(sql)
    data = cursor.fetchone()
    
    return success(data)
           
@app.route('/reply/add') 
def replyadd():
    (conn, cursor) = getConn()
    contentId = request.query.contentId
    content = request.query.content
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    try:
        sql2 = "update content set replyNum=replyNum+1 where id=%s" % contentId
        cursor.execute(sql2)
        sql1 = "insert into reply(contentId, content, replyUserId, replyUserNickename) value(%s, '%s', %s, '%s')" % (contentId, content, userId, userNickename)
        cursor.execute(sql1)
        
        conn.commit()
        insertId = cursor.lastrowid
        return success(insertId)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '回覆失敗')
    
@app.route('/reply/edit') 
def replyedit():
    (conn, cursor) = getConn()
    id = request.query.id
    content = request.query.content
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    try:
        sql = "update reply set content='%s',replyUserId=%s,replyUserNickename='%s' where id=%s and replyUserId=%s" % (content, userId, userNickename, id, userId)
        cursor.execute(sql)
        conn.commit()
        return success(None)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '編輯回覆失敗')
    
@app.route('/reply/delete') 
def replydelete():
    (conn, cursor) = getConn()
    id = request.query.id
    sessionId = request.query.sessionId
    userinfo = getloginuserinfo(sessionId)
    userId = userinfo['id']
    userNickename = userinfo['nickname']
    
    if userId <= 0:
        return error(1, '請先登入')

    sql = "select id,content,replyUserId,replyUserNickename,addTime,contentId from reply where isDel=0 and id=%s" % id
    cursor.execute(sql)
    contentdata = cursor.fetchone()
    
    if contentdata is None:
        return error(1, '回覆不存在')

    try:
        sql2 = "update content set replyNum=replyNum-1 where id=%s" % contentdata['contentId']
        cursor.execute(sql2)
        sql1 = "update reply set isDel=1 where id=%s and replyUserId=%s" % (id, userId)
        cursor.execute(sql1)
        
        conn.commit()
        return success(None)
    except MySQLdb.Error as e:
        conn.rollback()
        return error(1, '刪除回覆失敗')

if __name__ == "__main__":
    app.run(host='127.0.0.1', port=1091)

輸出:

D:\workspace\studys\study_pys\pc_app\dist>D:\software\Python310\python.exe D:\workspace\studys\study_bbs\start_web_bottle.py
Bottle v0.12.25 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:1091/
Hit Ctrl-C to quit.

相關文章