Spark 网页式 开发 (四)

接着上篇讲的,上篇说的 通过 Janino 实现了代码动态加载的过程,那么接下来我讲解下 后台的操作吧。毕竟网页式开发 肯定就需要一个网站,而网站也需要和后端交互,就需要后台了。

因为本人不是专门写后台的,所以就想找个最简单的后台开发,想到自己有python基础,就决定使用 bottle 作为后台 进行开发。

刚接触bottle的时候就被他吸引了,写一个网站就需要5、6行代码就可以跑起来,实在是太方便了。

好了,扯远了,将我这边在bottle中的开发的代码展示下。

<code># encoding=utf8
import os
import socket
import traceback

import yaml
from beaker.middleware import SessionMiddleware
from bottle import Bottle, run, request, static_file, template, redirect, BaseRequest, response

from application.action import *
from application.util import *

os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
import logging
import logging.config
import json

'''
stop-python
pid=`ps -ef|grep /home/appadmin/python3|grep -v grep|awk '{print $2}'`
echo $pid
kill -9 $pid


pip3 install DBUtils
pip3 install bottle
pip3 install breaker
pip3 install cx-Oracle
pip3 install pyyaml
pip3 install tornado
pip3 install requests
pip3 install lxml

'''


# scp -r [email protected]:/Users/zhonglieming/PycharmProjects/pythonWeb ~/python_project/
# scp -r [email protected]:/Users/zhonglieming/PycharmProjects/pythonWeb ~/python_project/
class BottleDemo:
\t@staticmethod
\tdef get_request_ip():
\t\t'''获取请求方的ip'''
\t\ttry:
\t\t\tip = request.remote_addr
\t\t\treturn ip
\t\texcept Exception as e:
\t\t\tlogging.error(e)
\t
\t@staticmethod
\tdef check_login_user():
\t\ts = request.environ.get('beaker.session') # 获取session
\t\tusername = s.get('user', None) # 从session中获取Key为user的值,是上面登陆的时候保存进来的
\t\tif username:
\t\t\treturn username
\t\telse:
\t\t\treturn None
\t
\t@staticmethod
\tdef get_pre_job_search_content(oracle_dbs, login_name):
\t\t
\t\tconn = oracle_dbs['DABAO_T']
\t\tif socket.gethostname() == 'sg-tdnifi-1.800best.com':
\t\t\tconn = oracle_dbs['DABAO_T9']
\t\telif socket.gethostname() == 'localhost':
\t\t\tconn = oracle_dbs['uat']
\t\t
\t\tpre_query_data = conn.db_query('''
\t\tselect * from(
\t\t\tselect
\t\t\t\tproject_name,
\t\t\t\tquery_content,
\t\t\t\trow_number() over (partition by login_name order by created_time desc) as rk
\t\t\t\tfrom ge_bi_contract_log
\t\t\t\twhere user_action='search_job'
\t\t\t\t\tand login_name='%s' and user_action='search_job' order by created_time desc
\t\t\t)res where rk=1 ''' % (str(login_name).lower()), True)
\t\tif pre_query_data:
\t\t\tquery_data = {'project_name' : str(pre_query_data[0]['project_name']),
\t\t\t\t\t\t 'query_content': str(pre_query_data[0]['query_content'])}
\t\telse:
\t\t\tquery_data = {'project_name': 'Spark_Thai9Analysis', 'query_content': ''}

\t\tquery_data['login_user'] = login_name
\t\tquery_data['active_index'] = 0
\t\treturn query_data
\t
\tdef __init__(self):
\t\t
\t\tself.log = logging.getLogger("BottleDemo")
\t\t# 避免出现 413 Request Entity Too Large
\t\tBaseRequest.MEMFILE_MAX = 1024 * 1024 * 5 # (or whatever you want)
\t\tself.app = Bottle()
\t\tself.app.install(OraclePlugin('oracle_dbs'))
\t\tself.user_permission = {'bl06250': 100, 'test': 10}
\t\tself.page_permission = {'page_table': 0, 'user_action': 90, 'data_table_config': 10, 'partition_table': 10,
\t\t\t\t\t\t\t\t'data_sync' : 20, 'jira_info': 20}
\t\tself.action_dict = {
\t\t\t\t\t\t\t 'page_table': (0, JobAction()), 'jobs': (0, JobAction())
\t\t

\t\t
\t\[email protected]('/static/:path#.+#')
\t\tdef server_static(path):
\t\t\treturn static_file(path, root='./static/', download=False)
\t\t
\t\[email protected](404)
\t\tdef error404(data):
\t\t\tself.log.error('404===' + str(data))
\t\t\tredirect('/login')
\t\t
\t\[email protected](500)
\t\tdef error500(error):
\t\t\tself.log.error('500===', error)
\t\t\tredirect('/login')
\t\t
\t\[email protected]('/')
\t\tdef except_url():
\t\t\tredirect('/login')
\t\t
\t\[email protected]('/:sub_url')
\t\tdef login_form(sub_url):
\t\t\tif sub_url != 'login':
\t\t\t\tself.log.info(sub_url + '-->login')
\t\t\t\tredirect('/login')
\t\t\treturn template('login', login_info="", pre_url="none")
\t\t
\t\[email protected]('/logout')
\t\tdef logout():
\t\t\tname = self.check_login_user()
\t\t\tself.log.info(name + ' logout')
\t\t\trequest.environ.get('beaker.session').delete()
\t\t\tredirect('/login')

\t\t
\t\t# 用户登录操作
\t\[email protected]('/login')
\t\tdef login(oracle_dbs):
\t\t\tname = request.forms.username
\t\t\tpassword = request.forms.password
\t\t\tpre_url = request.forms.pre_url
\t\t\t
\t\t\tif (str(name).lower() == 'bl06250' and password == 'zhonglieming') or str(name).lower() == 'test':
\t\t\t\tlogging.info(self.get_request_ip() + " go to login,username is " + name + ',ok.')
\t\t\t\t# 把username这个变量用安全字符串usafe加密,httponly指不允许通过javascript获取cookie,降低用户信息泄露风险,
\t\t\t\t# max_age = 600指这个cookie的有效期为600秒,600秒后就会过期,用户需要重新登录。
\t\t\t\t# response.set_cookie('username', name, secret='usafe', httponly=True, max_age=600)
\t\t\t\t# response.set_cookie('password', password, secret='psafe', httponly=True, max_age=600)
\t\t\t\t
\t\t\t\ts = request.environ.get('beaker.session')
\t\t\t\ts['user'] = name.lower()
\t\t\t\ts.save()
\t\t\t\tif pre_url == 'none':
\t\t\t\t\treturn template('page_table', self.get_pre_job_search_content(oracle_dbs, name))
\t\t\t\telse:
\t\t\t\t\tredirect(pre_url)
\t\t\telse:
\t\t\t\tlogging.info(self.get_request_ip() + " go to login,username is " + name + ', failed')
\t\t\t\treturn template('login', login_info='username or password error', pre_url=pre_url)
\t\t
\t\[email protected]('/tabs/tables/:sub_url', method='GET')
\t\tdef tables_web(sub_url):
\t\t\ttry:
\t\t\t\t
\t\t\t\tparams = request.GET.decode('utf8')
\t\t\t\tname = self.check_login_user()
\t\t\t\tif name:
\t\t\t\t\treturn template('data_table', table_name=sub_url, db_type=params['db_type'],
\t\t\t\t\t\t\t\t\tcollect_date=params['collect_date'], login_user=name)
\t\t\t\telse:
\t\t\t\t\tothers = []
\t\t\t\t\tfor key, v in params.items():
\t\t\t\t\t\tothers.append(key + '=' + v)
\t\t\t\t\tif others != []:
\t\t\t\t\t\tsub_url = sub_url + '?' + '&'.join(others)
\t\t\t\t\treturn template('login', login_info='please first login', pre_url="/tabs/tables/" + sub_url)
\t\t\texcept Exception as ie:
\t\t\t\ttraceback.print_exc()

\t\t\t\tself.log.error(str(ie))
\t\t
\t\[email protected]('/nav_bar/:sub_url', method='GET')
\t\tdef nav_bar_link(oracle_dbs, sub_url):
\t\t\tlogin_name = self.check_login_user()
\t\t\t
\t\t\tif login_name:
\t\t\t\tself.log.info('[%s ip(%s)]: nav_bar/%s' % (login_name, self.get_request_ip(), sub_url))
\t\t\t\tactive_index = self.action_dict.get(sub_url, (-1, None))[0]
\t\t\t\t
\t\t\t\tif self.user_permission[login_name] >= self.page_permission[sub_url]:
\t\t\t\t\t
\t\t\t\t\tif active_index == 0:
\t\t\t\t\t\treturn template(sub_url, self.get_pre_job_search_content(oracle_dbs, login_name))
\t\t\t\t\telif active_index > 0:
\t\t\t\t\t\treturn template(sub_url, login_user=login_name, active_index=active_index)
\t\t\t\t\telse:
\t\t\t\t\t\tredirect('/login')
\t\t\t\telse:
\t\t\t\t\tredirect('/login')
\t\t\telse:
\t\t\t\tself.log.info('[匿名登录 ip(%s)]: /jobs/%s' % (self.get_request_ip(), sub_url))
\t\t\t\treturn template('login', login_info='please first login', pre_url="nav_bar/" + sub_url)
\t\t
\t\[email protected]("/tabs/:parent_url/:sub_url", method='POST')
\t\tdef partition_table(oracle_dbs, parent_url, sub_url):
\t\t\tif parent_url in self.action_dict:
\t\t\t\tlogin_name = self.check_login_user()
\t\t\t\taction = self.action_dict[parent_url][1]
\t\t\t\tif login_name is None:
\t\t\t\t\tself.log.info('[匿名登录 ip(%s)]: /jobs/%s' % (self.get_request_ip(), sub_url))
\t\t\t\t\tredirect('/login')
\t\t\t\telse:
\t\t\t\t\tself.log.info('[%s ip(%s)]: tabs/%s/%s' % (login_name, self.get_request_ip(), parent_url, sub_url))
\t\t\t\t\t
\t\t\t\t\tif sub_url in ['table_config_update', 'add_one_reord', 'update_job_other',
\t\t\t\t\t\t\t\t 'update_job'] and login_name != 'bl06250':
\t\t\t\t\t\treturn json.dumps({'success' : False, 'rows': [], 'total': 0,
\t\t\t\t\t\t\t\t\t\t 'errorMsg': 'Sorry,user[%s] have not Permission' % login_name},
\t\t\t\t\t\t\t\t\t\t ensure_ascii=False)
\t\t\t\t\telse:
\t\t\t\t\t\treturn action.execute_action(oracle_dbs, login_name, sub_url, request.POST.decode('utf8'))
\t\t\telse:
\t\t\t\tredirect('/login')
\t\t
\t\[email protected]('after_request')
\t\tdef enable_cors():
\t\t\t"""
\t\t\t钩子函数,处理请求路由之后需要做什么的事情

\t\t\t:return:
\t\t\t"""
\t\t\tresponse.headers['Access-Control-Allow-Origin'] = '*'
\t
\tdef run(self):
\t\t
\t\t# 设置session参数
\t\tsession_opts = {'session.type' : 'file', # 以文件的方式保存session
\t\t\t\t\t\t'session.cookei_expires': 1800, # session过期时间为3600秒
\t\t\t\t\t\t# ,最后发现在session的配置参数中有一个参数timeout,如果我们使用session的方式,从描述上来看,我们使用timeout参数更加合理。
\t\t\t\t\t\t# 尝试将配置'session.cookie_expires': 30,修改为'session.timeout': 30,session在30秒后失效,说明这里应该使用timeout参数。
\t\t\t\t\t\t'session.timeout' : 1800, # session过期时间为3600秒
\t\t\t\t\t\t'session.data_dir' : '/tmp/sessions', # session存放路径
\t\t\t\t\t\t'session.auto' : True}
\t\tlogging.config.dictConfig(yaml.load(open('logging.yaml', 'r')))
\t\t
\t\tweb_port = 8080
\t\trun(SessionMiddleware(self.app, session_opts), host=socket.gethostname(), port=web_port, reloader=True,
\t\t\tdebug=False, server="tornado")
/<code>

上述就是程序运行的入口,代码写法和 Spring的写法类似,不过python作为python,就是写起来简单,。

简单的实现了用户登录 和 页面跳转。

在前台页面用户登录的时候,会触发

@self.app.post('/login') ,如果登录的用户名是bl06250,那么就登录成功,跳转到


Spark 网页式 开发 (四)

登录成功


反之 就继续留在登录页面

Spark 网页式 开发 (四)

登录失败,username or password error


,而当用户登录成功,就会在页面中修改代码,那么代码修改完提交的时候就需要通过

@self.app.route("/tabs/:parent_url/:sub_url", method='POST')

这个地方 进行 post请求,数据以json的形式到后台,被后台解析,去执行

return action.execute_action(oracle_dbs, login_name, sub_url, request.POST.decode('utf8'))

这里的内部实现就是处理 用户代码查询、修改 操作。

下一篇章,给大家 展示


Spark 网页式 开发 (四)

JobAction 内部的代码。


分享到:


相關文章: