def route_login(request): """ 登录页面的路由函数 """ headers = { 'Content-Type': 'text/html', } log('login, cookies', request.cookies) if request.method == 'POST': form = request.form() u = User(form) if u.validate_login(): user = User.find_by(username=u.username) # 设置 session session_id = random_str() session[session_id] = user.id headers['Set-Cookie'] = 'user={}'.format(session_id) log('headers response', headers) # 登录后定向到 / return redirect('/', headers) # 显示登录页面 body = template('login.html') header = response_with_headers(headers) r = header + '\r\n' + body return r.encode(encoding='utf-8')
def test_read(): todos = Todo.all() # log('test read', todos) t = Todo.find(1) assert t is not None, 't is none' assert t.id == 1, 'id error' log('id 1 的 todo 是 ', t.task)
def save(self): """ 用 all 方法读取文件中的所有 model 并生成一个 list 把 self 添加进去并且保存进文件 """ # log('debug save') models = self.all() # log('models', models) # 如果没有 id,说明是新添加的元素 if self.id is None: # 设置 self.id # 先看看是否是空 list if len(models) == 0: # 我们让第一个元素的 id 为 1(当然也可以为 0) self.id = 1 else: m = models[-1] # log('m', m) self.id = m.id + 1 models.append(self) else: # index = self.find(self.id) index = -1 for i, m in enumerate(models): if m.id == self.id: index = i break log('debug', index) models[index] = self l = [m.__dict__ for m in models] path = self.db_path() save(l, path)
def form(self): body = urllib.parse.unquote(self.body) args = body.split('&') f = {} log('form debug', args, len(args)) for arg in args: k, v = arg.split('=') f[k] = v return f
def add_cookies(self): """ height=169; user=gua """ cookies = self.headers.get('Cookie', '') kvs = cookies.split('; ') log('cookie', kvs) for kv in kvs: if '=' in kv: k, v = kv.split('=') self.cookies[k] = v
def index(request): """ 主页的处理函数, 返回主页的响应 """ header = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n' session_id = request.cookies.get('user', '') user_id = session.get(session_id) todo_list = Todo.find_all(user_id=user_id) log('index debug', user_id, todo_list) body = template('todo_index.html', todos=todo_list) r = header + '\r\n' + body return r.encode(encoding='utf-8')
def find_all(cls, **kwargs): ms = [] log('kwargs, ', kwargs, type(kwargs)) k, v = '', '' for key, value in kwargs.items(): k, v = key, value all = cls.all() for m in all: # 也可以用 getattr(m, k) 取值 if v == m.__dict__[k]: ms.append(m) return ms
def route_profile(request): log('profile cookies', request.cookies) header = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n' # body = '<h1>消息版</h1>' body = template('profile.html') session_id = request.cookies.get('user', '') user_id = session.get(session_id, -1) user = '' if user_id != -1: user = User.find_by(id=int(user_id)) body = body.replace('{{user}}', str(user)) r = header + '\r\n' + body return r.encode(encoding='utf-8')
def find_by(cls, **kwargs): """ 用法如下,kwargs 是只有一个元素的 dict u = User.find_by(username='******') """ log('kwargs, ', kwargs, type(kwargs)) k, v = '', '' for key, value in kwargs.items(): k, v = key, value all = cls.all() for m in all: # 也可以用 getattr(m, k) 取值 if v == m.__dict__[k]: return m return None
def response_for_path(path): path, query = parsed_path(path) request.path = path request.query = query log('path and query', path, query) """ 根据 path 调用相应的处理函数 没有处理的 path 会返回 404 """ r = { '/static': route_static, } # 注册外部的路由 r.update(simpletodo_routes) r.update(user_routes) r.update(todo_routes) # response = r.get(path, error) return response(request)
def route_login(request): """ 登录页面的路由函数 """ headers = { 'Content-Type': 'text/html', # 'Set-Cookie': 'height=169; gua=1; pwd=2; Path=/', } # log('login, headers', request.headers) log('login, cookies', request.cookies) username = current_user(request) if request.method == 'POST': form = request.form() u = User(form) if u.validate_login(): # session_id = random_str() # session[session_id] = u.username # headers['Set-Cookie'] = 'user={}'.format(session_id) user = User.find_by(username=u.username) session_id = random_str() session[session_id] = user.id headers['Set-Cookie'] = 'user={}'.format(session_id) # headers['Set-Cookie'] = 'user_id={}'.format(user.id) result = '登录成功' log('headers response', headers) else: result = '用户名或者密码错误' else: result = '' body = template('login.html') body = body.replace('{{result}}', result) body = body.replace('{{username}}', username) header = response_with_headers(headers) r = header + '\r\n' + body # log('login', r) return r.encode(encoding='utf-8')
def run(host='', port=3000): """ 启动服务器 """ # 初始化 socket 套路 # 使用 with 可以保证程序中断的时候正确关闭 socket 释放占用的端口 log('start at', '{}:{}'.format(host, port)) with socket.socket() as s: s.bind((host, port)) # 无限循环来处理请求 while True: # 监听 接受 读取请求数据 解码成字符串 s.listen(3) connection, address = s.accept() r = connection.recv(1100) r = r.decode('utf-8') log('完整请求') log(r.replace('\r\n', '\n')) log('请求结束') # log('ip and request, {}\n{}'.format(address, r)) # 因为 chrome 会发送空请求导致 split 得到空 list # 所以这里判断一下防止程序崩溃 if len(r.split()) < 2: continue path = r.split()[1] # 设置 request 的 method request.method = r.split()[0] request.add_headers(r.split('\r\n\r\n', 1)[0].split('\r\n')[1:]) # 把 body 放入 request 中 request.body = r.split('\r\n\r\n', 1)[1] # 用 response_for_path 函数来得到 path 对应的响应内容 response = response_for_path(path) # 把响应发送给客户端 connection.sendall(response) log('完整响应') try: log(response.decode('utf-8').replace('\r\n', '\n')) except Exception as e: log('异常', e) log('响应结束') # 处理完请求, 关闭连接 connection.close()