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

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

程式碼:

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.view import view_config
from pyramid.response import 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

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 = Response(result, content_type='text/plain')
    response.headers['Server'] = 'pyramid-Web-Framework'
        
    return response

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

def success( data = {}):
    return responsex(0, '', data)

@view_config(context=Exception, renderer='json')
def index(request):
    (conn, cursor) = getConn()
    result = "此站介面使用python.pyramid實現,<a href='api.html' target='_blank'>介面列表</a>"
    response = Response(result, content_type='text/plain')
    response.headers['Server'] = 'pyramid-Web-Framework'
    
    return response

def register(request):
    (conn, cursor) = getConn()
    username = request.params.get("username")
    password = request.params.get("password")
    nickname = request.params.get("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, '註冊失敗')

def login(request):
    (conn, cursor) = getConn()
    username = request.params.get("username")
    password = request.params.get("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失敗')
     
def logout(request):
    (conn, cursor) = getConn()
    sessionId = request.params.get("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失敗')

def getuserinfo(request):
    (conn, cursor) = getConn()
    sessionId = request.params.get("sessionId")
    userinfo = getloginuserinfo(sessionId)
    return success(userinfo)
    
def postlist(request):
    (conn, cursor) = getConn()
    page = request.params.get("page")
    keyword = request.params.get("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})

def postdetail(request):
    (conn, cursor) = getConn()
    id = request.params.get("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)

def postadd(request):
    (conn, cursor) = getConn()
    title = request.params.get("title")
    content = request.params.get("content")
    sessionId = request.params.get("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, '發帖失敗')

def postedit(request):
    (conn, cursor) = getConn()
    id = request.params.get("id")
    title = request.params.get("title")
    content = request.params.get("content")
    sessionId = request.params.get("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, '編輯帖子失敗')

def postdelete(request):
    (conn, cursor) = getConn()
    id = request.params.get("id")
    sessionId = request.params.get("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, '刪除帖子失敗')
    
def replylist(request):
    (conn, cursor) = getConn()
    page = request.params.get("page")
    contentId = request.params.get("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})
    
def replydetail(request):
    (conn, cursor) = getConn()
    id = request.params.get("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)
           
def replyadd(request):
    (conn, cursor) = getConn()
    contentId = request.params.get("contentId")
    content = request.params.get("content")
    sessionId = request.params.get("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, '回覆失敗')
    
def replyedit(request):
    (conn, cursor) = getConn()
    id = request.params.get("id")
    content = request.params.get("content")
    sessionId = request.params.get("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, '編輯回覆失敗')
    
def replydelete(request):
    (conn, cursor) = getConn()
    id = request.params.get("id")
    sessionId = request.params.get("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__':
    with Configurator() as config:
        config.add_route('index', '/')
        config.add_view(index, route_name='index')
        
        config.add_route('register', '/user/register')
        config.add_view(register, route_name='register')
        
        config.add_route('login', '/user/login')
        config.add_view(login, route_name='login')
        
        config.add_route('logout', '/user/logout')
        config.add_view(logout, route_name='logout')
        
        config.add_route('getuserinfo', '/user/getuserinfo')
        config.add_view(getuserinfo, route_name='getuserinfo')
        
        config.add_route('postlist', '/post/list')
        config.add_view(postlist, route_name='postlist')
        
        config.add_route('postdetail', '/post/detail')
        config.add_view(postdetail, route_name='postdetail')
        
        config.add_route('postadd', '/post/add')
        config.add_view(postadd, route_name='postadd')
        
        config.add_route('postedit', '/post/edit')
        config.add_view(postedit, route_name='postedit')
        
        config.add_route('postdelete', '/post/delete')
        config.add_view(postdelete, route_name='postdelete')
        
        config.add_route('replylist', '/reply/list')
        config.add_view(replylist, route_name='replylist')
        
        config.add_route('replydetail', '/reply/detail')
        config.add_view(replydetail, route_name='replydetail')
        
        config.add_route('replyadd', '/reply/add')
        config.add_view(replyadd, route_name='replyadd')
        
        config.add_route('replyedit', '/reply/edit')
        config.add_view(replyedit, route_name='replyedit')
        
        config.add_route('replydelete', '/reply/delete')
        config.add_view(replydelete, route_name='replydelete')
        
        app = config.make_wsgi_app()
    
    print("http://127.0.0.1:1093/")
    server = make_server('0.0.0.0', 1093, app)
    server.serve_forever()

輸出:

D:\workspace\studys\study_pys\pc_app\dist>D:\software\Python310\python.exe D:\workspace\studys\study_bbs\start_web_pyramid.py
http://127.0.0.1:1093/

相關文章