[python] 大华ICC平台事件FTP摆渡 报警事件与报警图片打包上传FTP
订阅ICC平台事件后,运行程序监听事件推送。
下载事件中的图片,并于json打包后存放至FTP,便于网闸搬运
from flask import Flask, request, json
import requests
import base64
import json
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pksc1_v1_5
from Crypto.PublicKey import RSA
import urllib3
import time
import zipfile
import os
from ftplib import FTP
from datetime import datetime
# 禁用SSL警告
urllib3.disable_warnings()
# 平台鉴权信息修改登录地址为实际地址
base_url = "https://33.x.x.x"
username = "system"
password = "xxxxx"
client_id = "xxxxx"
client_secret = "xxxxx"
magic_id = ''
headers = {}
token = ""
def rsa_encrypt(string, public_key):
# 使用RSA公钥加密
rsakey = RSA.importKey(public_key)
cipher = Cipher_pksc1_v1_5.new(rsakey)
encrypt_text = cipher.encrypt(string.encode())
cipher_text_tmp = base64.b64encode(encrypt_text)
return cipher_text_tmp.decode()
def get_public_key():
# 获取公钥
public_key = json.loads(requests.get(base_url + "/evo-apigw/evo-oauth/1.0.0/oauth/public-key", verify=False).text)['data']['publicKey']
return public_key
def login():
global magic_id
global token
# 登录获取token
public_key = get_public_key()
print("public_key:\t", public_key)
encrypted_pass = rsa_encrypt(password, '-----BEGIN PUBLIC KEY-----\n' + public_key + '\n-----END PUBLIC KEY-----')
print("encrypted_pass:\t" + encrypted_pass)
data = {
"grant_type": "password",
"username": username,
"password": encrypted_pass,
"client_id": client_id,
"client_secret": client_secret,
"public_key": public_key
}
# 发送登录请求
response = json.loads(requests.post(base_url + "/evo-apigw/evo-oauth/1.0.0/oauth/extend/token", json=data, verify=False).text)
try:
token = response['data']['access_token']
magic_id = response['data']['magicId']
print('更新全局token,magicId', token, magic_id)
except:
print('登录失败,服务器返回信息:', response)
print("Token:", token)
print('MagicId:', magic_id)
return token
app = Flask(__name__)
@app.before_request
def log_request_info():
print(f"Request: {request.method} {request.path}")
if request.method == 'GET':
# 获取 GET 请求的参数
params = request.args
print("GET Params: {}".format(params))
elif request.method == 'POST':
# 尝试解析 JSON 数据
try:
json_data = request.get_json()
print("POST JSON: {}".format(json.dumps(json_data, indent=4)))
if 'info' in json_data and 'alarmPicture' in json_data['info']:
image_name = json_data['info']['alarmPicture'].split('/')[-1]
download_image(json_data['info']['alarmPicture'], image_name)
zip_and_upload(json_data, image_name)
except Exception as e:
# 如果解析失败,则获取表单数据
params = request.form
print("POST Params: {}".format(params))
def download_image(image_url, image_name):
print("开始下载",image_url)
global token
token = login()
url = f"https://33.x.x.x/evo-pic/{image_url}?token={token}&oss_addr=33.x.x.x:8925"
response = requests.get(url, verify=False)
if response.status_code == 200:
with open(image_name, 'wb') as f:
f.write(response.content)
print(f"Image {image_name} downloaded successfully.")
else:
print(f"Failed to download image {image_name}. Status code: {response.status_code}")
print(response.text)
def zip_and_upload(json_data, image_name):
timestamp = int(time.time() * 1000)
zip_filename_base = f"SK_ALARM_{timestamp}"
zip_filename = f"{zip_filename_base}.zip"
temp_zip_filename = f"{zip_filename}.temp"
#网闸不摆渡.temp格式的文件,但zip格式会直接摆渡,如果直接使用.zip后缀,可能在文件上传完成前就被网闸删除,因此先使用temp作为临时后缀,等文件上传完成后,再删除临时后缀
with zipfile.ZipFile(zip_filename, 'w') as zipf:
zipf.writestr("data.json", json.dumps(json_data, indent=4))
zipf.write(image_name)
ftp = FTP()
ftp.connect('33.x.x.x', 21)#FTP地址
ftp.login('xxxxx', 'xxxxx')#账号,密码
with open(zip_filename, 'rb') as f:
ftp.storbinary(f'STOR {temp_zip_filename}', f)
ftp.rename(temp_zip_filename, zip_filename)
ftp.quit()
print(f"ZIP file {zip_filename} uploaded to FTP server successfully.")
os.remove(zip_filename)
os.remove(image_name)
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
@app.route('/<path:path>', methods=['GET', 'POST'])
def catch_all(path):
return f"Request received for {request.method} {request.path}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=10001)