import sys,os,shutil,re
panelPath = os.getenv('BT_PANEL')
os.chdir(panelPath)
sys.path.append("class/")
import public,time,json,xmltodict


try:
    from watchdog.observers import Observer
    from watchdog.events import FileSystemEventHandler
except :
    os.system(public.get_run_pip("[PIP] install watchdog"))
    from watchdog.observers import Observer
    from watchdog.events import FileSystemEventHandler

class panelWatch:

    def __init__(self):
        pass

    def start_watching(self):
        """
        启动文件监听（监听php程序目录修改）

        """
        sites = public.M('sites').field('id,type,path').where('type=?',("PHP",)).where("project_type = 'PHP'",()).select()      
        watchs = []
        for x in sites:   
            try:
                path = x['path']
            except :
                pass
            
            #兼容thinkphp
            if os.path.exists(path + '/thinkphp') and  os.path.exists(path + '/public') : path = path + '/public'
           
            if os.path.exists(path):                
                watcher = Observer()            
                watcher.schedule(event_handler=FileEventHandler(), path = path, recursive = False)
                watcher.start()
                watchs.append(watcher)
        try:
            re_path = panelPath + '/data/restart.watch'
            while True:
                if os.path.exists(re_path):
                    os.remove(re_path)
                    self.start_watching()
                time.sleep(1)
        except:
            for x in watchs:
                x.stop()


def get_config_rules(sitePath):        
    """
    获取站点url重写规则
    """
    try:          
        try:
            if not os.path.exists(sitePath + '/web_config'): os.makedirs(sitePath + '/web_config')
                
            config_path = sitePath + '/web_config/rewrite.config'            
            data = public.loads_json(config_path)
            if not 'rules' in data: data['rules'] = {}                    
        except :           
            data = {}
            data['rules'] = {}
   
        if not 'rule' in data['rules']:
            data['rules']['rule'] = []
        else:
            list = data['rules']['rule'];
            if type(list) != type([1,]):
                data['rules']['rule'] = [list]
        return data
    except Exception as ex:        
        return False

def str_strip(str1):
    """
    匹配新旧配置
    """
    str1 = str1.replace('encoding="UTF-8"','')
    str1 = re.sub('\s+', '', str1).strip()
    return str1

class FileEventHandler(FileSystemEventHandler):
    """
    文件读写监听
    """
    def on_created(self, event):
        pass
        #print(event)

    def on_deleted(self, event):
        pass
        #print(event)

    def on_modified(self, event):
        """
        文件修改事件(wp程序修改web.config文件后，自动解析web.config)

        """            
        web_path = public.format_path(event.src_path)
        
         #兼容wp,后台配置自动修改web.config
        if re.search("/web\.config$",web_path):
            site_path = web_path.replace('/web.config','')
            check_wp = "{}/wp-config.php".format(site_path)  

            if os.path.exists(check_wp):    
                conf = public.readFile(web_path)            
                default_config = {"configuration": {"location": {"@path": ".", "@allowOverride": "false", "@inheritInChildApplications": "false", "system.webServer": {"rewrite": {"rules": {"@configSource": "web_config\\rewrite.config"}}, "defaultDocument": {"@configSource": "web_config\\default.config"}, "httpErrors": {"@configSource": "web_config\\httpErrors.config"}, "handlers": {"@configSource": "web_config\\php.config"}}}}}      
                new_conf = public.format_xml(public.dumps_json(default_config))
                       
                if str_strip(conf) != str_strip(new_conf):
                   
                    public.writeFile(web_path + '_backup',conf)
                
                    #处理伪静态，重定向，反向代理
                    new_list = get_config_rules(site_path)   
                    print(new_list)
                    tmps = re.findall('<rule[\s+>][\w\W]+?/rule>',conf)                
                    if len(tmps) > 0: 
                        for nVal in tmps:
                            try:
                                item = xmltodict.parse(nVal)
                                if item['rule']:
                                    if '@name' in item['rule']:
                                        item['rule']['@name'] = item['rule']['@name'].replace('_rewrite','') + '_rewrite'
                                    else:
                                        item['rule']['@name'] = public.GetRandomString(6) + '_rewrite'
                                    is_count = 0
                                    for x in new_list['rules']['rule']:
                                        if x['@name'] == item['rule']['@name']:
                                            is_count = 1
                                            break;
                                    if not is_count: new_list['rules']['rule'].append(item['rule'])
                            except :  pass                        
                            config_path = site_path + '/web_config/rewrite.config'
                            public.writeFile(config_path, public.format_xml(public.dumps_json(new_list)))
                   
                        #处理默认页                        
                        tmp2 = re.search('(<defaultDocument([\w\W]+)</defaultDocument>)',conf)
                        if tmp2:
                            d_config = tmp2.groups()[0]
                            tmp3 = re.findall('<add.*value="(.+?)".*/>',conf)                
                            if len(tmp3) > 0: 
                                d_list = []
                                for x in tmp3: d_list.append({"@value":x})                        
                                d_conf = {"defaultDocument": {"files": {"clear": {}, "add": d_list }}}

                                config_path = site_path + '/web_config/default.config'
                                public.writeFile(config_path, public.format_xml(public.dumps_json(d_conf)))
                
                    public.writeFile(site_path + '/web.config', new_conf)

   
    
    def on_moved(self, event):
        """
        文件移动/重命名
        """
        if re.search("\.user\.ini$",event.src_path):
            os.rename(event.dest_path,event.src_path)
            #print(".user.ini禁止修改")

if __name__ == '__main__':
    event_handler = FileEventHandler()
    watch = panelWatch()
    watch.start_watching()
    