洋老板 IOS 热更新和更新操作
创建一个 django 项目,app 为 app01
修改 setting.py
# 修改
ALLOWED_HOSTS = ['*']
# 注释
#'django.middleware.csrf.CsrfViewMiddleware',
# 添加
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
修改 urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('ios_update/', views.ios_update),
path('ios_hotupdate/', views.ios_hotupdate),
]
修改 views.py
from django.shortcuts import render
import os
import sys
import hashlib
import pymysql
import time
import urllib.request
# Create your views here.
# OPY 是控制是否远程传输 apk 到测试服务器。1:启用,0:停用
OPY = 0
def mysql_getcon():
conn = pymysql.connect(host='192.168.0.200', port=3306, user='root', passwd='020GuangZhOU', db='chenwenjian')
return conn
def refresh_redis():
url_save = 'http://admin.ibaboss.com/admin/base/load?lt=appVersion'
urllib.request.urlretrieve(url_save)
def ios_update(req):
res = ''
if req.method == 'POST':
sv_no = req.POST.get("sv_no", None)
force_up = req.POST.get("force_up", 0)
remark = req.POST.get("remark", None)
# 获取当前时间
struct_time = time.localtime()
app_time = time.strftime('%Y-%m-%d %H:%M:%S', struct_time)
# 插入数据库
try:
sql = "INSERT INTO base_app_version(app_type, mv_no, rv_no, sv_no, mv_url, rv_url, sv_url, mv_sum, rv_sum, sv_sum, force_up, ext1, ext2, remark, create_time, status_time, status) VALUES (0, %s, '', '', '', '', '', '', '', '', %s, '', '', %s, %s,%s, 1);"
t_sql = "INSERT INTO ibalife_base.base_app_version(app_type, mv_no, rv_no, sv_no, mv_url, rv_url, sv_url, mv_sum, rv_sum, sv_sum, force_up, ext1, ext2, remark, create_time, status_time, status) VALUES (0, '%s', '', '', '', '', '', '', '', '', '%s', '', '', '%s', '%s','%s', 1);"
param = (sv_no, force_up, remark, app_time, app_time)
res = t_sql % (param)
#print(res)
conn = mysql_getcon()
cursor = conn.cursor()
cursor.execute(sql, param)
conn.commit()
refresh_redis()
except:
conn.rollback()
raise
finally:
cursor.close()
conn.close()
return render(req, "index.html", {"result": res})
def ios_hotupdate(req):
res = ''
if req.method == "POST":
# print("前端数据: ", req.POST)
# print("file:", req.FILES)
# 上传到 attachments 文件夹中
for item in req.FILES:
obj = req.FILES.get(item)
pkg_name = obj.name.replace('jpsv', '').replace('.zip', '')
print(obj.name)
mv_no = ".".join(pkg_name.split(".")[0:3])
#print(mv_no)
if sys.platform == "win32":
if os.path.exists("attachments\\" + mv_no):
pass
else:
os.mkdir("attachments\\" + mv_no)
filename = "attachments\\" + mv_no + "\\" + obj.name
else:
if os.path.exists("attachments/" + mv_no):
pass
else:
os.mkdir("attachments/" + mv_no)
filename = "attachments/" + mv_no + "/" + obj.name
f = open(filename, 'wb')
for line in obj.chunks():
f.write(line)
f.close()
# 获取当前时间
struct_time = time.localtime()
app_time = time.strftime('%Y-%m-%d %H:%M:%S', struct_time)
# 获取url
mv_url = "http://app.ibaboss.com/bossres/ios/sv/%s/%s"%(mv_no, obj.name)
# 获取 md5值
ran_b64_salt = "nTtjpPyEiHb8kxcsqCwo6P75BJzOmK1kOoEXWcjUKb/1Vy+P4w17KRFiB6qmjaPjlUARcTzvgRzxBg0Cex8issPY3lYiNQAm+nTDvpGWm9qWysBPshQQ3r7pVUjJwWbUYx7920rB4izy+YbwbzEETLDLRj6opnr5KqTM/x9Mln4="
salt = ran_b64_salt
md5code = hashlib.md5(open(filename, 'rb').read()).hexdigest()
mv_sum = hashlib.md5((md5code + salt).encode("utf8")).hexdigest()
# 组成 mysql 语句
sql = "UPDATE base_app_version SET rv_no = '', sv_no = %s, mv_url = '', rv_url = '', sv_url = %s, mv_sum = '', rv_sum = '', sv_sum = %s, ext1 = '', ext2 = '', create_time = %s, status_time = %s, status = 1 WHERE app_type = 0 AND mv_no = %s;"
t_sql = "UPDATE ibalife_base.base_app_version SET rv_no = '', sv_no = '%s', mv_url = '', rv_url = '', sv_url = '%s', mv_sum = '', rv_sum = '', sv_sum = '%s', ext1 = '', ext2 = '', create_time = '%s', status_time = '%s', status = 1 WHERE app_type = 0 AND mv_no = '%s';"
param = (pkg_name, mv_url, mv_sum, app_time, app_time, mv_no)
res = t_sql % param
# 创建 mysql 连接
try:
conn = mysql_getcon()
cursor = conn.cursor()
cursor.execute(sql, param)
conn.commit()
#refresh_redis()
except:
conn.rollback()
raise
finally:
# 关闭
cursor.close()
conn.close()
# 使用 linux cmd 命令 scp apk
if OPY == 1:
apk_folder = "/ios_upload/attachments/" + mv_no
#print(apk_folder)
os.system("sshpass -p 'ibaboss' scp -o \"StrictHostKeyChecking=no\" -r "+apk_folder+" root@192.168.0.232:/iba/ibaboss/bossres/ios/sv/")
return render(req, "hot.html", {"result": res})
添加一个 templates 文件夹
创建三个文件: base.html, hot.html, index.html
# base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IOS测试环境更新</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<script src="/static/jquery.min.js"></script>
</head>
<body style="margin-left: 20px; margin-right: 20px">
<h1>IOS 测试环境更新平台</h1>
<ul class="nav nav-tabs">
<li id="update" role="presentation" class="active"><a href="/ios_update/">IOS 更新</a></li>
<li id="hot" role="presentation"><a href="/ios_hotupdate/">IOS 热更新</a></li>
</ul>
{% block content %}
{% endblock %}
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
</body>
</html>
# hot.html
{% extends "base.html" %}
{% block content %}
<form class="form-horizontal" action="/ios_hotupdate/" method="post" enctype="multipart/form-data" style="margin-top: 10px">
<div class="form-group">
<label class="col-sm-1 control-label">上传热更新包</label>
<div class="col-sm-2">
<input type="file" name="upload" style="margin-top: 4px" >
</div>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<hr>
<h3>请把 SQL 语句给运维</h3>
<textarea class="form-control" rows="8">{{ result }}</textarea>
<script>
$(function () {
$('#hot').addClass('active');
$('#update').removeClass('active');
})
</script>
{% endblock %}
# index.html
{% extends "base.html" %}
{% block content %}
<form class="form-horizontal" action="/ios_update/" method="post" style="margin-top: 10px">
<div class="form-group">
<label class="col-sm-1 control-label">版本号</label>
<div class="col-sm-2">
<input type="text" class="form-control" name="sv_no" placeholder="eg: 3.9.4">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label" style="padding-top: 0px">是否强制更新</label>
<div class="col-sm-2">
<input type="checkbox" name="force_up" value="1" >
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">更新提示</label>
<div class="col-sm-2">
<textarea class="form-control" name="remark" rows="6"></textarea>
</div>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<hr>
<h3>请把 SQL 语句给运维</h3>
<textarea class="form-control" rows="8">{{ result }}</textarea>
{% endblock %}
编译 docker 镜像
cd /tmp
vi ios_upload.df
FROM python:3.5
MAINTAINER from klvchen
RUN pip install django && pip install pymysql && echo "deb http://mirrors.ustc.edu.cn/debian jessie main contrib non-free \ndeb-src http://mirrors.ustc.edu.cn/debian jessie main contrib non-free \ndeb http://mirrors.ustc.edu.cn/debian jessie-proposed-updates main contrib non-free \ndeb-src http://mirrors.ustc.edu.cn/debian jessie-proposed-updates main contrib non-free" > /etc/apt/sources.list && apt-get update && apt -y install sshpass && apt-get clean
docker build -f ios_upload.df -t python_django:19.03.0
# mkdir /iba/ios_upload -p
# 上传项目到这里
vi docker-compose.yaml
version: '3.4'
services:
klvchen:
image: python_django:19.03.0
ports:
- 8003:8003
command:
- /bin/bash
- -c
- |
cd /ios_upload
python manage.py runserver 0.0.0.0:8003
volumes:
- /iba/ios_upload/ios_upload:/ios_upload
docker-compose up -d


浙公网安备 33010602011771号