Files
yakpanel-core/class/panelMessage.py
2026-04-07 02:04:22 +05:30

340 lines
11 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#coding: utf-8
# +-------------------------------------------------------------------
# | YakPanel
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
# +-------------------------------------------------------------------
# | Author: hwliang <2020-05-18>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
# | 消息提醒
# +-------------------------------------------------------------------
import time
import json
import public
try:
from YakPanel import cache
except :
import cachelib
cache = cachelib.SimpleCache()
class panelMessage:
os = 'linux'
def set_send_status(self, id, data):
'''
@name 设置消息发送状态
@author cjxin <2021-04-12>
@param args dict_obj{
id: 消息标识,
data
}
@return dict
'''
public.M('messages').where('id=?',id).update(data)
return public.returnMsg(True, public.lang("Setup successful!"))
"""
获取官网推送消息,一天获取一次
"""
def get_cloud_messages(self,args):
# yakpanel 暂时不用
return public.returnMsg(True, public.lang("Synchronization success!"))
try:
ret = cache.get('get_cloud_messages')
if ret: return public.returnMsg(True, public.lang("同步成功1!"))
data = {}
data['version'] = public.version()
data['os'] = self.os
sUrl = public.GetConfigValue('home') + '/api/wpanel/get_messages'
import http_requests
http_requests.DEFAULT_TYPE = 'src'
info = http_requests.post(sUrl,data).json()
# info = json.loads(public.httpPost(sUrl,data))
for x in info:
count = public.M('messages').where('level=? and msg=?',(x['level'],x['msg'],)).count()
if count: continue
pdata = {
"level":x['level'],
"msg":x['msg'],
"state":1,
"expire":int(time.time()) + (int(x['expire']) * 86400),
"addtime": int(time.time())
}
public.M('messages').insert(pdata)
cache.set('get_cloud_messages',86400)
return public.returnMsg(True, public.lang("同步成功!"))
except:
return public.returnMsg(False, public.lang("同步失败!"))
def get_messages(self,args = None):
'''
@name 获取消息列表
@author hwliang <2020-05-18>
@return list
'''
ikey = 'get_message'
data = cache.get(ikey)
if not data:
if not public.is_aarch():
public.run_thread(self.get_cloud_messages,args=(args,))
data = public.M('messages').where('state=? and expire>?',(1,int(time.time()))).order("id desc").select()
cache.set(ikey,data,86400)
return data
def get_messages_all(self,args = None):
'''
@name 获取所有消息列表
@author hwliang <2020-05-18>
@return list
'''
public.run_thread(self.get_cloud_messages,args=(args,))
data = public.M('messages').order("id desc").select()
return data
def get_message_find(self,args = None,id = None):
'''
@name 获取指定消息
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@return dict
'''
if args:
id = int(args.id)
data = public.M('messages').where('id=?',id).find()
return data
def create_message(self,args = None,level=None,msg=None,expire=None):
'''
@name 创建新的消息
@author hwliang <2020-05-18>
@param args dict_obj{
level: 消息级别(info/warning/danger/error),
msg: 消息内容
expire: 过期时间
}
@return dict
'''
if args:
level = args.level
msg = args.msg
expire = args.expire
pdata = {
"level":level,
"msg":msg,
"state":1,
"expire":int(time.time()) + (int(expire) * 86400),
"addtime": int(time.time())
}
public.M('messages').insert(pdata)
return public.returnMsg(True, public.lang("Created successfully!"))
def status_message(self,args = None,id = None,state = None):
'''
@name 设置消息状态
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识,
state: 消息状态(0.已忽略, 1.正常)
}
@return dict
'''
if args:
id = int(args.id)
state = int(args.state)
public.M('messages').where('id=?',id).setField('state',state)
return public.returnMsg(True, public.lang("Set up successfully!"))
def remove_message(self,args = None,id = None):
'''
@name 删除指定消息
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@return dict
'''
if args:
id = int(args.id)
public.M('messages').where('id=?',id).delete()
return public.returnMsg(True, public.lang("Successfully deleted!"))
def remove_message_level(self,level):
'''
@name 删除指定消息
@author hwliang <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
public.M('messages').where('(level=? or level=? or level=? or level=?) and state=?',(level,level+'15',level+'7',level+'3',1)).delete()
return True
def remove_message_all(self):
public.M('messages').where('state=?',(1,)).delete()
return True
def is_level(self,level):
'''
@name 指定消息是否忽略
@author hwliang <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
if public.M('messages').where('level=? and state=?',(level,0)).count():
return False
else:
return True
def init_msg_module(self, module):
"""
初始化消息通道, 迁移自windows
@module 消息通道模块名称
@author lx
"""
try:
import os, sys
if not os.path.exists('class/msg'): os.makedirs('class/msg')
panelPath = "/www/server/panel"
sfile = 'class/msg/{}_msg.py'.format(module)
if not os.path.exists(sfile): return False
sys.path.insert(0, "{}/class/msg".format(panelPath))
msg_main = __import__('{}_msg'.format(module))
try:
public.reload_mod(msg_main)
except:
pass
return eval('msg_main.{}_msg()'.format(module));
except:
return None
def get_default_channel(self, args=None):
"""获取面板默认消息通道
Returns:
channel: str/None没有安装消息通道的情况下返回None。
"""
default_channel_pl = "/www/server/panel/data/default_msg_channel.pl"
default_channel = public.readFile(default_channel_pl)
if default_channel:
return public.returnMsg(True, default_channel)
return public.returnMsg(False, public.lang(""))
# def get_default_channel(self):
# """获取面板默认消息通道,默认是邮箱,其次默认选择已安装的第一个消息通道
# Returns:
# channel: str/None没有安装消息通道的情况下返回None。
# """
# from config import config
# c = config()
# get = public.dict_obj()
# configs = c.get_msg_configs(get)
# installed = []
# for channel, obj in configs.items():
# if "setup" in obj and obj["setup"]:
# installed.append(channel)
# if "default" in obj and obj["default"]:
# return channel
# if "mail" in installed:
# return "mail"
# if installed:
# return installed[0]
# return None
def notify(self, args):
"""发送通知
Args:
args (dict):
title: 消息标题
msg: 消息内容
channel: 消息通道
"""
msg = ""
if "msg" in args:
body = args.msg
title = ""
if "title" in args:
title = args.title
sm_type = None
if "sm_type" in args:
sm_type = args.sm_type
sm_args = {}
if "sm_args" in args:
sm_args = json.loads(args.sm_args)
channel = None
channels = []
if "channel" in args:
channel = args.channel
if channel.find(",") != -1:
channels = channel.split(",")
else:
channels = [channel]
if not channel:
channel_res = self.get_default_channel()
if "msg" in channel_res:
channels = [channel_res["msg"]]
if not channels:
return False
try:
from config import config
c = config()
get = public.dict_obj()
msg_channels = c.get_msg_configs(get)
error_channel = []
channel_data = {}
for ch in channels:
msg_data = {}
# 根据不同的消息通道准备不同的内容
if ch == "mail":
# 如果邮箱通知,没有标题直接跳过
if not title: continue
msg_data = {
"msg": body.replace("\n", "<br/>"),
"title": title
}
if ch in ["dingding", "weixin", "feishu"]:
# 钉钉类必须有消息内容
if not body: continue
msg_data["msg"] = body
if ch in ["sms"]:
# 短信必须指定短信模板名
if not sm_type: continue
msg_data["sm_type"] = sm_type
msg_data["sm_args"] = sm_args
if not msg_data:
channel_data[ch] = args
# print("channel data:")
# print(channel_data)
# 即时推送
from panelPush import panelPush
pp = panelPush()
error_count = 0
push_res = pp.push_message_immediately(channel_data)
if push_res["status"]:
channel_res = push_res["msg"]
for ch, res in channel_res.items():
if not res["status"]:
if ch in msg_channels:
error_channel.append(msg_channels[ch]["title"])
error_count +=1
if error_count == len(channels):
return False
return True
except Exception as e:
return False