#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Windows面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2020 宝塔软件(http://www.bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 沐落 <cjx@bt.cn>
# +-------------------------------------------------------------------
import sys,os,time,json,re
panelPath = os.getenv('BT_PANEL')
os.chdir(panelPath);
sys.path.append("class/")
import public,db,time,html,panelPush

try:
    from BTPanel import cache
except :
    from cachelib import SimpleCache
    cache = SimpleCache()

class btFilter_push:

    name = 'btFilter'
    setup_path = os.getenv('BT_SETUP')
    conf_path = '{}/plugin/{}/config.json'.format(panelPath,name)
            
    __push = None
    def __init__(self):
        self.__push = panelPush.panelPush()
   
    #-----------------------------------------------------------start 添加推送 ------------------------------------------------------
    """
    @ 获取插件版本信息   
    """
    def get_version_info(self,get):
        """
        获取版本信息
        """
        data = {}
        data['ps'] = ''
        data['version'] = '1.0'
        data['date'] = '2020-07-14'
        data['author'] = '宝塔'
        data['help'] = 'http://www.bt.cn'
        return data

    """
    @获取推送模块配置
    """
    def get_module_config(self,get):

        data = []        
        s_list = {'all':{}}
        if os.path.exists(self.conf_path): 
            s_data = json.loads(public.readFile(self.conf_path))
            for x in s_data: s_list[x] = s_data[x]
        
        keys = {'total':'总拦截次数','create':'创建文件次数','write':'修改文件次数','delete':'删除文件次数'}
        
        for skey in s_list:
            item = {}
            item['project'] = skey
            item['title'] = '{}防篡改拦截告警'.format(skey)
            if skey == 'all':
                item['title'] = '全部项目'
            item['type'] = 'btFilter'
            item['keys'] = []            
            for x in keys:
               item['keys'].append({'key':x,'val':keys[x]})
            item['count'] = 1
            item['cycle'] = 600
            item['push'] = ['dingding','weixin']
            item['helps'] = ['注意：此功能需购买专业版后使用']
            data.append(item)
                
        return data


    #-----------------------------------------------------------end 添加推送 ------------------------------------------------------

    """
    @格式化数据
    @conf 推送任务配置 {"project":"web","title":"web防篡改推送","key":"total","count":10,"cycle":60,"module":"dingding","interval":600}
    @total 统计数据
    @return  {"title":"宝塔面板","msg":"测试推送","to_email":"","sms_type":"","sms_argv":"","module":"dingding"}
    """
    def get_push_data(self,conf,total):
        if conf['module'] in ['sms']: 
            return public.returnMsg(False,"暂不支持模板，跳过.")            
            
        c_key = public.md5(conf['title'])
        s_key = "{}_interval".format(c_key)
        if cache.get(s_key): 
            return public.returnMsg(False,"未达到间隔时间，跳过.")            

        n_count = 0
        try:
            if conf['project']:
                n_count = total[conf['project']][conf['key']]
            else:
                n_count = total[conf['key']]
        except :pass

        if "index" in conf: n_count = n_count - conf['index']   #减去上次推送索引         
        
        count = cache.get(c_key)
        if not count:
            cache.set(c_key,n_count,conf['cycle'])
            #return public.returnMsg(False,"首次统计，不推送.")
        
        count = cache.inc(c_key,n_count)
        if count >= conf['count']:
            if conf['interval']:cache.set(s_key,1,conf['interval'])
            return self.__get_result(conf,count)
        return public.returnMsg(False,"未达到阈值，跳过.")
       
    """
    @获取总拦截统计(全部取出来)
    """
    def get_total(self):
        data = {'total':0 }
        sdata = self.__get_configs()        
        for skey in sdata:            
            data[skey] = {"total":0,"write":0,"create":0,"rename":0,"delete":0 ,"move":0};             
            total_path = "{}/{}/total/{}/total.json".format(self.setup_path,self.name,skey)
            if os.path.exists(total_path):
                data[skey]['total'] = 0
                ret = json.loads(public.readFile(total_path))              
                for x in ret['total']:  
                    data[skey][x] += ret['total'][x]
                    data[skey]['total'] += ret['total'][x]              
            
            for x in ['write','create','rename','delete','move']:                
                s_path = "{}/{}/total/{}/{}.{}".format(self.setup_path,self.name,skey,public.format_date("%Y-%m-%d"),x)
                if os.path.exists(s_path):                    
                    n_count = os.path.getsize(s_path)
                    data[skey][x] += n_count
                    data[skey]['total'] += n_count
                    data['total'] += n_count
        return data;
    
    def __get_configs(self):
        data = {}
        try:
            data = json.loads(public.readFile(self.conf_path))
        except : pass
        return data

    """
    @格式化返回
    """
    def __get_result(self,data,count):
        result = {
            'status':True,
            'msg':'触发拦截',
            'index':count,
            'data':{
                  'title':data['title'],
                  'to_email':'',
                  'sms_type':'',
                  'sms_argv':{},
                  'title':data['title'],
                  'msg':'您的项目[{}] {}秒内触发了{}次拦截'.format(data['project'],data['cycle'],count)
            }
        }
        
        p_msg = "项目名称：{}".format(data['project'])
        if not data['project']: p_msg = "项目名称：全部"

        for m_module in data['module'].split(','):
            result[m_module] = self.__push.format_msg_data()

            if m_module in ['dingding','weixin']:
                result[m_module]['msg'] ="".join((
                    "#### 堡塔防篡改拦截提醒\n\n",
                    ">服务器 ："+ public.GetLocalIp() +"\n\n ",
                    ">"+ p_msg +"\n\n ",
                    ">触发周期："+ str(data['cycle']) +" 秒\n\n ",
                    ">拦截次数：<font color=#ff0000>"+ str(count) +" 次</font>\n\n ",
                    ">拦截时间："+time.strftime('%Y-%m-%d %X',time.localtime())+"\n\n",
                    ">拦截状态：<font color=#20a53a>防护成功</font>"))
            print(result)
        return result
