#coding: utf-8
#-----------------------------
# 安装脚本
#-----------------------------
import sys,os,shutil
panelPath = os.getenv('BT_PANEL')
os.chdir(panelPath)
sys.path.append("class/")
import public,tarfile,time,re

class panel_apache:
    _name = 'apache'
    _version = None
    _setup_path = None

    def __init__(self,name,version,setup_path):
        self._name = name
        self._version = version
        self._setup_path = setup_path

    def install_soft(self,downurl,update = False):
        os.system("net stop http /y")
        status = public.get_server_status('W3SVC')
        if status >=0:
            public.bt_print('准备卸载IIS..')
            os.system("iisreset /stop")
            public.change_server_start_type('W3SVC',-1)
            public.WriteReg(r'SYSTEM\CurrentControlSet\services\HTTP','Start',0)

        vc_version = '2008'
        public.bt_print('正在检测vc++库..')
        if not public.check_setup_vc(vc_version):
            public.bt_print('正在安装vc' + vc_version + '...')
            if not public.setup_vc(vc_version): return public.returnMsg(False,'VC' + vc_version + '安装失败!');

        x_64path = 'C:/Windows/SysWOW64'
        if not os.path.exists(x_64path + '/api-ms-win-crt-runtime-l1-1-0.dll') and not os.path.exists(x_64path + '/downlevel/api-ms-win-crt-runtime-l1-1-0.dll'):
            public.bt_print('vc2015安装失败,尝试修补系统..')
            temp = self._setup_path + '/temp/vc2015.zip'
            public.downloadFile(downurl + '/win/panel/data/vc2015_x64.zip',temp)

            tmpPath = self._setup_path + "/temp/vc2015"
            #解压到临时目录
            import zipfile
            zip_file = zipfile.ZipFile(temp)
            for names in zip_file.namelist():
                zip_file.extract(names,tmpPath)
            zip_file.close()

            tmpPath = tmpPath.replace("/","\\")
            os.system("xcopy /s /c /e /y /r %s %s" % (tmpPath,x_64path.replace("/","\\")))

        path = self._setup_path
        temp = self._setup_path + '/temp/' + self._name + self._version +'.zip'

        if os.path.exists(temp):
            os.remove(temp)
        #配置PHP上传路径
        public.bt_print('正在更改PHP上传路径...')
        self.set_php_upload_path()

        public.bt_print('正在下载安装包...')
        public.downloadFile(downurl + '/win/apache_new/'+ self._name + self._version +'.zip',temp)
        if not os.path.exists(temp): return public.returnMsg(False,'文件下载失败,请检查网络!');

        if public.get_server_status(self._name) >= 0:
            is_update = True
            public.delete_server(self._name)
        public.kill("httpd.exe");
        public.kill("php-cgi.exe");
        public.bt_print('正在解压...')
        import zipfile
        zip_file = zipfile.ZipFile(temp)
        for names in zip_file.namelist():
            zip_file.extract(names,path)
        zip_file.close()

        if os.path.exists(self._setup_path + '/' + self._name + '/version.pl'): os.remove(self._setup_path + '/' + self._name + '/version.pl')

        if not update:
            #设置启动权限
            public.bt_print('正在配置目录权限（如果目录过大，则会消耗大量时间，请耐心等待）...')
            self.set_webserver_access()

        public.bt_print('正在配置' + self._name + '...')
        iniPath = self._setup_path + '/' + self._name + '/conf/httpd.conf'
        config = public.readFile(iniPath).replace('[PATH]',self._setup_path.replace('/','\\') + '\\apache')
        public.writeFile(iniPath,config)

        public.bt_print('正在安装' + self._name + '服务...')
        password = public.readFile('data/www')

        #rRet = public.create_server(self._name,self._name,self._setup_path + '/' + self._name + '/bin/httpd.exe','-k runservice',"Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上，由于其跨平台和安全性被广泛使用，是最流行的Web服务器端软件之一",'www',password)
        #zend需要授权c:/Windows目录，无法www用户无法授权
        #rRet = public.create_server(self._name,self._name,self._setup_path + '/' + self._name + '/bin/httpd.exe','-k runservice',"Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上，由于其跨平台和安全性被广泛使用，是最流行的Web服务器端软件之一")

        os.system('{}/apache/bin/httpd -k install -n apache'.format(self._setup_path ))
        time.sleep(3);
        if public.get_server_status(self._name) >= 0:
            public.M('config').where("id=?",('1',)).setField('webserver','apache')
            if public.set_server_status(self._name,'start'):
                public.bt_print('安装成功.')
                self.create_default_site()
                return public.returnMsg(True,self._name + '安装成功')
            else:
                return public.returnMsg(False,'启动失败，请检查配置文件是否错误!')

        public.bt_print('安装失败.')
        return True
        #return rRet;


    def get_ip_address(self):

        """
        取本地外网IP
        """
        try:

            url = 'http://pv.sohu.com/cityjson?ie=utf-8'
            str = public.httpGet(url)
            ipaddress = re.search('\d+.\d+.\d+.\d+', str).group(0)

            return ipaddress
        except:
            try:
                url = 'https://www.bt.cn/Api/getIpAddress'
                str = public.httpGet(url)
                return str
            except:
                False

    def create_default_site(self):
        """
        @name 创建默认站点
        """

        t_path = '{}/data/default.site'.format(public.get_panel_path())
        if not os.path.exists(t_path):
            try:

                print('正在创建默认站点...')
                siteName = self.get_ip_address()
                if not siteName: return

                find = public.M('config').where("id=?",('1',)).find()
                if not find: return

                import panelSite,json
                site_obj = panelSite.panelSite()

                args = public.dict_obj()
                args.webname = json.dumps({"domain":siteName,"domainlist":[],"count":0})
                args.ps = '默认网站，将网站源码放入网站根目录即可访问'

                args.path = '{}/{}'.format(find['sites_path'],siteName)
                args.version = '00'
                args.port = '80'
                args.ftp = 'false'
                args.sql = 'false'

                res = site_obj.AddSite(args)
                if res['siteStatus']:
                    print('默认站点创建成功，访问地址: http://{}'.format(siteName))
                public.writeFile(t_path,'True')
            except:pass

    def uninstall_soft(self):
        try:
            if os.path.exists(self._setup_path + '/phpmyadmin'):
                shutil.rmtree(self._setup_path + '/phpmyadmin')
        except :
            pass
        if public.get_server_status(self._name) >= 0:
            public.delete_server(self._name)
            time.sleep(2)
            shutil.rmtree(self._setup_path  + '/' + self._name)

        return public.returnMsg(True,'卸载成功!');

    #更新软件
    def update_soft(self,downurl):
        sfile = self._setup_path + '\\' + self._name + '\\conf\\httpd.conf'
        dfile =  self._setup_path + '\\' + self._name + '\\conf\\httpd.conf.backup'
        shutil.copy (sfile,dfile)
        rRet = self.install_soft(downurl,True)
        if not rRet['status'] : rRet;

        shutil.copy(dfile,sfile)
        os.remove(dfile);
        return public.returnMsg(True,'更新成功!');

    #由于C:/Windows无法增加www权限，故修改上传目录到C:/Temp
    def set_php_upload_path(self):
        phpPath = self._setup_path + '/php'
        phps = []
        if os.path.exists(phpPath):
            for filename in  os.listdir(phpPath):

                if os.path.isdir(phpPath + '/' + filename):
                    try:
                        phps.append(int(filename))
                    except :
                        pass
        for version in phps:
            iniPath = phpPath + '/' + str(version)+ '/php.ini'

            if os.path.exists(iniPath):
                conf = public.readFile(iniPath)
                conf = re.sub(';?upload_tmp_dir.+','upload_tmp_dir="C:/Temp"',conf);
                public.writeFile(iniPath,conf)
        return True


    #恢复网站权限（仅适配apache下www权限）
    def set_webserver_access(self):

        setupPath = public.format_path(os.getenv("BT_SETUP"))
        tpath = setupPath+ '/panel/script/BtTools.exe'
        public.ExecShell("{} add_user_bywww {}".format(tpath,os.getenv("BT_SETUP")))

        che_user = public.ExecShell("net user")[0];
        if che_user.find("www") < 0:
            print('www用户创建失败,请检查安全软件是否拦截')

        pwdpath = setupPath + '/panel/data/www'
        if not os.path.exists(pwdpath):
            print('"www用户创建失败,请检查安全软件是否拦截1.')

        if not os.path.exists('C:/Temp'): os.makedirs('C:/Temp')
        public.set_file_access("C:/Temp","IIS_IUSRS",public.file_all,True)

        user = 'www'
        data = public.M('config').where("id=?",('1',)).field('sites_path').find();

        if data['sites_path'].find('/www/') >=0 :
            wwwroot = os.getenv("BT_SETUP")[:2] + '/wwwroot'
            if not os.path.exists(wwwroot): os.makedirs(wwwroot)

            backup_path = os.getenv("BT_SETUP")[:2] + '/backup'
            if not os.path.exists(backup_path): os.makedirs(backup_path)

            public.M('config').where('id=?',(1,)).setField('backup_path',backup_path)
            public.M('config').where('id=?',(1,)).setField('sites_path',wwwroot)

            data = public.M('config').where("id=?",('1',)).field('sites_path').find();

        #完全控制权限
        paths = ["C:/Temp", public.GetConfigValue('logs_path'), public.GetConfigValue('setup_path') + '/apache' ,data['sites_path'],'{}/wwwlogs'.format(setupPath),'{}/php'.format(setupPath),'{}/temp'.format(setupPath) ]

        #只读权限
        flist = []
        for x in paths: public.get_paths(x,flist)
        try:
             #批量设置上层目录只读权限
            for f in flist:
                print("正在设置 %s 权限" % f)
                public.set_file_access(f,user,public.file_read,False)
        except :
            print("批量设置只读权限失败，可能会影响apache使用，如apache无法启动，请手动给【{}】添加【{}】只读权限".format(','.join(flist),user))


        paths.append('{}/waf_apache'.format(setupPath))
        paths.append('{}/total_apache'.format(setupPath))
        paths.append('{}/speed_apache'.format(setupPath))

        for f in paths:
            if not os.path.exists(f): continue
            print("正在设置 %s 及其子目录权限" % f)
            public.set_file_access(f,user,public.file_all,True)

        public.set_file_access(os.getenv("BT_SETUP") + '/apache',user,public.file_all)

        return public.returnMsg(True,'权限恢复成功，当前仅恢复apache启动所需权限，网站权限需要手动恢复!')


