任务提醒摆件HTTP服务器端功能解析

※TIPS:python文件直接命令行执行方式参考:怎么用cmd命令行窗口运行python文件_tyq_666的博客-优快云博客_cmd运行python文件

命令行执行语句:

打开命cmd命令提示行窗口,输入 cd + 存放.py文件夹路径,按下回车键(Enter键)

输入 py HTTP_Server.py,按下回车键(Enter键),即可成功运行服务器

※TIPS:postman调试工具官网:Postman API Platform

目前使用一个全局字典存放所有的task任务,服务器掉电后重新初始化;

※postman测试,直接用JSON格式收包,可以接收中文字符

任务存放格式如下:

字段:  
key键值:由服务器自动分配self.keyvalue = keyvalue
title任务名称self.taskname = taskname
address任务执行的地点self.address = address
S-time任务开始时间self.begintime = begintime
E-time任务结束时间self.endtime = endtime
contents任务具体内容self.contents = contents
step阶段self.step = step
importance重要性self.importance = importance
status状态self.status = status

目前实现的功能(所有数据传输通过json字符串传输)注意:IP地址为主机地址,用ipconfig指令查看:

1、客户端通过get服务,获取所有任务信息,目前通过get服务直接返回在网页body体中;

实现效果:

①通过浏览器直接访问对应的IP服务,获取全部任务:http://192.168.28.16:8080/alltask

※192.168.28.16是对应的本地服务器IP地址,/alltask是目前允许访问的url

 ②通过postman调试工具get服务,获取全部任务信息:

 postman获取的结果:

<html>

<head>
	<title>TO-DO_Screen</title>
</head>

<body>
	<p>Welcome to TO-DO_Screen!</p>
	<p>ALL_TASK_begin</p>
	<p>{"keyvalue": 1, "taskname": "Learn how to use TO-DO_Screen", "address": "kitchen", "begintime": "19:00",
		"endtime": "21:00", "contents": "default_contents", "step": "default_step", "importance": "default_importance",
		"status": "default_status"}</p>
	<p>{"keyvalue": 2, "taskname": "Learn how to add task", "address": "office", "begintime": "8:00", "endtime": "9:00",
		"contents": "default_contents", "step": "default_step", "importance": "default_importance", "status":
		"default_status"}</p>
	<p>{"keyvalue": 3, "taskname": "Learn how to del task by keyvalue", "address": "bedroom", "begintime": "22:00",
		"endtime": "23:00", "contents": "default_contents", "step": "default_step", "importance": "default_importance",
		"status": "default_status"}</p>
	<p>ALL_TASK_end</p>
	<p>You accessed path: /alltask</p>
</body>

</html>
GET request for /alltask

 

2、客户端通过post服务,追加指定任务,keyvalue由服务器自动分配,并且返回给客户端:

例:追加任务:sleeping

除keyvalue字段之外,其余字段均需要存在

post语句:

{"TASK_ID": "ADD", "keyvalue": 0, "taskname": "sleeping", "address": "bedroom", "begintime": "24:00", "endtime": "8:00", "contents": "default_contents", "step": "default_step", "importance": "default_importance", "status": "default_status"}

 TASK_ID_ADD-keyvalue:4;ADD_SUCCESS:可以看到服务器自动分配的keyvalue是4,并且追加成功;

再次get获取全部任务查看:

 

 3、客户端通过post服务,删除指定任务,keyvalue为唯一匹配点,并且返回给客户端:

如果不存在对应的任务返回信息,提示删除失败,如果有提示删除结果;

例:删除任务3:

除keyvalue字段之外,其余字段均发送空白即可

post语句:{"TASK_ID": "DEL", "keyvalue": 3, "taskname": "", "address": "", "begintime": "", "endtime": "", "contents": "", "step": "", "importance": "", "status": ""}

 TASK_ID_DEL-keyvalue:3;DEL_SUCCESS:可以看到提示删除任务3成功;

再次get获取全部任务查看:

  再次尝试删除任务3,因为任务3不存在,所以无法删除:

TASK_ID_DEL-keyvalue:3;DEL_Failed-no_keyvalue:提示没有对应的keyvalue,删除失败;

 4、客户端通过post服务,修改指定任务,keyvalue为唯一匹配点,需要修改的字段设置内容,不需要修改的字段默认为空即可,并且返回给客户端:

如果不存在对应的任务返回信息,提示修改失败,如果有提示修改结果;

例:修改任务2的开始时间和结束时间:

除keyvalue字段之外,其余需要修改的字段有内容即可,无需修改的字段发送空白即可

post语句:{"TASK_ID": "CHANGE", "keyvalue": 2, "taskname": "", "address": "", "begintime": "6:00", "endtime": "8:00", "contents": "", "step": "", "importance": "", "status": ""}

TTASK_ID_CHANGE-keyvalue:2;CHANGE_SUCCESS:可以看到提示修改任务3成功;

再次get获取全部任务查看,任务2的指定字段已被修改:

 再次尝试修改不存在的任务3,因为任务3不存在,所以无法修改:

TASK_ID_CHANGE-keyvalue:3;CHANGE_Failed-no_keyvalue:提示没有对应的keyvalue,修改失败;

※postman测试,直接用JSON格式收包,可以接收中文字符

 

 

 服务器端完成源码:

from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
import json
import copy
from collections import OrderedDict

# python 使用类创建结构体
class Taskclass(object):
    class Struct(object):
        def __init__(self, keyvalue, taskname, address, begintime, endtime, contents, step, importance, status):
            self.keyvalue = keyvalue
            self.taskname = taskname
            self.address = address
            self.begintime = begintime
            self.endtime = endtime
            self.contents = contents
            self.step = step
            self.importance = importance
            self.status = status

    def make_struct(self, keyvalue, taskname, address, begintime, endtime, contents, step, importance, status):
        return self.Struct(keyvalue, taskname, address, begintime, endtime, contents, step, importance, status)

#服务器结构体
class S(BaseHTTPRequestHandler):
    def do_HEAD(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    #get服务获取当前所有的任务
    def do_GET(self):
        paths = {
            '/alltask': {'status': 200}, #success
            '/fob': {'status': 404}, #cant find
            '/err': {'status': 500}  #failed
        }
        print(self.path)
        if self.path in paths:
            self.respond(paths[self.path])
        else:
            self.respond({'status': 500})
        logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
        self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))

    #追加或者削除任务
    def do_POST(self):
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself

        logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
                str(self.path), str(self.headers), post_data.decode('utf-8'))

        res = "Your TASK_STR: " + post_data.decode('utf-8')
        TASK_STR_json = ""
        TASK_DICT = {}
        TASK_STR_json = post_data.decode('utf-8')
        print(TASK_STR_json)
        print(type(TASK_STR_json))
        TASK_DICT = json.loads(TASK_STR_json)
        print(TASK_DICT)
        print(type(TASK_DICT))
        TASK_ID = ""
        TASK_ID = TASK_DICT["TASK_ID"]
        print(TASK_ID)
        if TASK_ID == "ADD" or TASK_ID == "DEL" or TASK_ID == "CHANGE":
            if TASK_ID == "ADD":
                keyvalue = Task_ADD(
                    TASK_DICT["taskname"],
                    TASK_DICT["address"],
                    TASK_DICT["begintime"],
                    TASK_DICT["endtime"],
                    TASK_DICT["contents"],
                    TASK_DICT["step"],
                    TASK_DICT["importance"],
                    TASK_DICT["status"]
                )
                res = res + "-TASK_ID_ADD-" + "keyvalue:" + str(keyvalue) + ";ADD_SUCCESS"
            if TASK_ID == "DEL":
                keyvalue = TASK_DICT["keyvalue"]
                Del_RES = Task_DEL(keyvalue)
                if Del_RES == 1:
                    res = res + "-TASK_ID_DEL-" + "keyvalue:" + str(keyvalue) + ";DEL_Failed-no_keyvalue"
                else:
                    res = res + "-TASK_ID_DEL-" + "keyvalue:" + str(keyvalue) + ";DEL_SUCCESS"
            if TASK_ID == "CHANGE":
                keyvalue = TASK_DICT["keyvalue"]
                CHANGE_RES = Task_CHANGE(keyvalue, TASK_DICT)
                if CHANGE_RES == 1:
                    res = res + "-TASK_ID_CHANGE-" + "keyvalue:" + str(keyvalue) + ";CHANGE_Failed-no_keyvalue"
                #未对应
                elif CHANGE_RES == 2:
                    res = res + "-TASK_ID_CHANGE-" + "keyvalue:" + str(keyvalue) + ";CHANGE_Failed-Dict_ERR"
                else:
                    res = res + "-TASK_ID_CHANGE-" + "keyvalue:" + str(keyvalue) + ";CHANGE_SUCCESS"
        else:
            res = res + "-TASK_ID_ERR"

        self.do_HEAD()
        # self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
        self.wfile.write("{}".format(res).encode('utf-8'))
        # self.wfile.write("POST request for {ASS}".format(data).encode('utf-8'))

    def respond(self, opts):
        response = self.handle_http(opts['status'], self.path)
        self.wfile.write(response)

    def handle_http(self, status_code, path):
        self.send_response(status_code)
        content = ""
        if status_code == 200:
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            task_str = ""
            task_str = print_Dict_Task(Dict_Task)
            content = '''
               <html><head><title>TO-DO_Screen</title></head>
               <body>
               <p>Welcome to TO-DO_Screen!</p>
               <p>ALL_TASK_begin</p>
               {}
               <p>ALL_TASK_end</p>
               <p>You accessed path: {}</p>
               </body></html>
               '''.format(task_str, path)
        return bytes(content, 'UTF-8')


global Dict_Task  #暂时用来全局存储任务队列的字典
global Task_KEY


#打印数据结构用的print函数
def print_Taskclass(testclass):
    str_out = ""
    str_out = "keyvalue:" + str(testclass.keyvalue) \
                + ";taskname:" + str(testclass.taskname)\
                + ";address:" + str(testclass.address)\
                + ";begintime:" + str(testclass.begintime)\
                + ";endtime:" + str(testclass.endtime) \
                + "contents:" + str(testclass.contents) \
                + ";step:" + str(testclass.step) \
                + ";importance:" + str(testclass.importance) \
                + ";status:" + str(testclass.status)
    print(str_out)
    # print(testclass.keyvalue)
    # print(testclass.taskname)
    # print(testclass.address)
    # print(testclass.begintime)
    # print(testclass.endtime)

#打印字典用的print函数
def print_Dict_Task(testdict):
    print(len(testdict))

    task_str_re = ""
    str_h = "<p>"
    str_t = "</p>"


    #直接print
    # for key in testdict:
    #     print_Taskclass(testdict[key])

    #单条数据转json类型
    for key in testdict:
        Dict_testSingle = {}
        Dict_testSingle = Dict_testSingle.clear()
        Dict_testSingle = OrderedDict()
        Dict_testSingle["keyvalue"] = testdict[key].keyvalue
        Dict_testSingle["taskname"] = testdict[key].taskname
        Dict_testSingle["address"] = testdict[key].address
        Dict_testSingle["begintime"] = testdict[key].begintime
        Dict_testSingle["endtime"] = testdict[key].endtime
        Dict_testSingle["contents"] = testdict[key].contents
        Dict_testSingle["step"] = testdict[key].step
        Dict_testSingle["importance"] = testdict[key].importance
        Dict_testSingle["status"] = testdict[key].status
        Task_json = json.dumps(Dict_testSingle)
        print(Task_json)
        print(type(Task_json))

        #服务器打包
        task_str_re = task_str_re + str_h + Task_json + str_t

        # students = json.loads(Task_json)
        # print(students)
        # print(type(students))
    return task_str_re


#Dict_Task追加任务
def Task_ADD(taskname, address, begintime, endtime, contents, step, importance, status):
    global Dict_Task
    global Task_KEY
    Task_KEY = Task_KEY + 1  #服务器自动分配KEY

    #新建task结构体
    myclass = Taskclass()
    t_taskclass = myclass.make_struct(Task_KEY, taskname, address, begintime, endtime, contents, step, importance, status)
    # print_Taskclass(t_taskclass)
    Dict_Task[Task_KEY] = copy.deepcopy(t_taskclass)
    print("Task:" + str(Task_KEY) + "-ADD_OK")
    return Task_KEY

#Dict_Task删除任务
def Task_DEL(keyvalue):
    global Dict_Task
    res = 0
    if keyvalue in Dict_Task:
        del(Dict_Task[keyvalue])
        print("Task:" + str(keyvalue) + "-DEL_OK")
    else:
        print("Task:" + str(keyvalue) + "-DEL_NG")
        res = 1
    return res

#Dict_Task修改任务
def Task_CHANGE(keyvalue, TASK_DICT):
    global Dict_Task
    res = 0
    if keyvalue in Dict_Task:
        if TASK_DICT["taskname"] != "":
            Dict_Task[keyvalue].taskname = TASK_DICT["taskname"]
        if TASK_DICT["address"] != "":
            Dict_Task[keyvalue].address = TASK_DICT["address"]
        if TASK_DICT["begintime"] != "":
            Dict_Task[keyvalue].begintime = TASK_DICT["begintime"]
        if TASK_DICT["endtime"] != "":
            Dict_Task[keyvalue].endtime = TASK_DICT["endtime"]
        if TASK_DICT["contents"] != "":
            Dict_Task[keyvalue].contents = TASK_DICT["contents"]
        if TASK_DICT["step"] != "":
            Dict_Task[keyvalue].step = TASK_DICT["step"]
        if TASK_DICT["importance"] != "":
            Dict_Task[keyvalue].importance = TASK_DICT["importance"]
        if TASK_DICT["status"] != "":
            Dict_Task[keyvalue].status = TASK_DICT["status"]
        print("Task:" + str(keyvalue) + "-CHANGE_OK")
    else:
        print("Task:" + str(keyvalue) + "-CHANGE_NG")
        res = 1
    return res


def run(server_class=HTTPServer, handler_class=S, port=8080):
    print("run()")
    logging.basicConfig(level=logging.INFO)
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    logging.info('Starting httpd...\n')
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print("httpd.server_close()")
    logging.info('Stopping httpd...\n')





if __name__ == '__main__':
    from sys import argv

    Dict_Task = {}
    Dict_Task = Dict_Task.clear()
    print(Dict_Task)
    Dict_Task = OrderedDict()
    Task_KEY = 0

    key = Task_ADD('Learn how to use TO-DO_Screen', 'kitchen', '19:00', "21:00", "default_contents", "default_step", "default_importance", "default_status")
    key = Task_ADD('Learn how to add task', 'office', '8:00', "9:00", "default_contents", "default_step", "default_importance", "default_status")
    key = Task_ADD('Learn how to del task by keyvalue', 'bedroom', '22:00', "23:00", "default_contents", "default_step", "default_importance", "default_status")
    # res = Task_DEL(1)
    #服务器打包
    ss = print_Dict_Task(Dict_Task)
    print(ss)


    if len(argv) == 2:
        run(port=int(argv[1]))
    else:
        run()

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值