#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Windows面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2020 宝塔软件(http://www.bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 沐落 <cjx@bt.cn>

# | 插件安装公共类
# +-------------------------------------------------------------------

import sys,os,shutil
panelPath = os.getenv('BT_PANEL')
panelSetup = os.getenv('BT_SETUP')
os.chdir(panelPath)
sys.path.append("class/")
import public

class panelInstall:
   
    def plugin_install(self,name,downurl,olist = []):
        """
         插件安装模板
         @name插件名称
         @downurl 下载节点
         @olist 需要下载的文件列表
        """       

        imp_path = "{}/plugin/{}".format(panelPath,name)
        if not imp_path in sys.path: sys.path.insert(0,imp_path)

        if not hasattr(public,"get_py_version"):  
            public.bt_print("请将面板升级到6.8.0及以上版本。")
            exit()

        if len(olist) == 0: olist.append('{}_main.py'.format(name))

        if public.get_server_status(name) >= 0: public.delete_server(name)

        plugin_path = panelPath + '/plugin/' + name
        if not os.path.exists(plugin_path): os.makedirs(plugin_path)

        os.system("del /s %s\*.pyc" % public.to_path(plugin_path))

        fileList = ['icon.png','info.json','index.html']
        fileList.extend(olist)

        for filename in fileList:
            local_name = '{}/{}'.format(plugin_path,filename);
            if local_name[-4:] == '.pyc':
                sfile = os.path.basename(local_name)
                os.rename(local_name,local_name.replace(sfile,'{}.pyc'.format(public.GetRandomString(8))))

            if local_name[-4:] == '.pyd':
                #先处理cp36-win_amd64.pyd
                if os.path.exists(local_name):
                    try:
                        _main = __import__('{}_main'.format(name))                       
                        public.mod_reload(_main)
                        os.remove(local_name)
                    except :
                        try:
                            os.rename(local_name,local_name.replace('.pyd','.pyc'))
                        except :
                            sfile = os.path.basename(local_name)
                            os.rename(local_name,local_name.replace(sfile,'{}.pyc'.format(public.GetRandomString(8))))
                        

                #继续处理*.pyd文件
                local_name = local_name.replace('.{}-win_amd64'.format(public.get_py_version()),'')
    
                if os.path.exists(local_name):
                    try:
                        _main = __import__('{}_main'.format(name))                        
                        public.mod_reload(_main)
                        os.remove(local_name)
                    except :
                        try:
                            os.rename(local_name,local_name.replace('.pyd','.pyc'))
                        except :
                            sfile = os.path.basename(local_name)
                            os.rename(local_name,local_name.replace(sfile,'{}.pyc'.format(public.GetRandomString(8))))
 
                d_url = '{}/win/install/plugin/{}/{}'.format(downurl,name,'{}.{}-win_amd64.pyd'.format(filename.replace('.pyd',''),public.get_py_version()))
            else:
                d_url = '{}/win/install/plugin/{}/{}'.format(downurl,name,filename)
            public.downloadFileByWget(d_url,local_name)
            if not os.path.exists(local_name):    
                public.bt_print("文件下载失败 ->> error : {}".format(d_url))
                exit()

            if local_name[-4:] == '.pyd':
                try:
                    import imp
                    _main = __import__('{}_main'.format(name))                        
                    public.mod_reload(_main)                    
                except :pass

        os.system("del /s %s\*.pyc" % public.to_path(plugin_path))

        public.bt_print("插件{}安装成功.".format(name))
        return True

    def soft_install(self,name,downurl,ulist = []):
        """
        软件安装
        @name 软件名称
        @downurl 下载完整地址
        @ulist 需要更新的列表   
        """
        
        soft_path = '{}/{}'.format(panelSetup,name)
        local_tmp = '{}/temp/{}'.format(panelSetup,name)
        if os.path.isfile(local_tmp): os.remove(local_tmp)
          
        if not os.path.exists(local_tmp): os.makedirs(local_tmp)
        if not os.path.exists(soft_path): os.makedirs(soft_path)


        if public.get_server_status(name) >= 0: public.delete_server(name)        

        temp = '{}/temp/{}.zip'.format(panelSetup,name)
        public.downloadFileByWget(downurl,temp)
        if os.path.getsize(temp) < 10: 
            public.bt_print('文件下载失败,请检查网络 --> error: {}'.format(downurl))
            exit()

        import zipfile
        zip_file = zipfile.ZipFile(temp)  
        for names in zip_file.namelist():  
            zip_file.extract(names,local_tmp)
        zip_file.close()

        local_path = local_tmp
        if os.path.exists('{}/{}'.format(local_tmp,name)): local_path = '{}/{}'.format(local_tmp,name)
           
        os.system("del /s %s\*.tmp" % public.to_path(soft_path))

        if len(ulist) > 0:
            os.system("del /s %s\*.tmp" % public.to_path(soft_path))
            for filename in ulist:
                spath =  '{}/{}'.format(soft_path,filename)
                
                #改名后批量删除旧文件，防止文件占用
                sfile = os.path.basename(spath)
                os.rename(spath,spath.replace(sfile,'{}.tmp'.format(public.GetRandomString(8))))

                if os.path.exists(spath): os.rename(spath,spath + '.tmp')

                os.system("echo f|xcopy /s /c /e /y /r {} {}".format(public.to_path(local_path  + '/' + filename),public.to_path(spath)))
        else:
            os.system("echo f|xcopy /s /c /e /y /r {} {}".format(public.to_path(local_path),public.to_path(soft_path)))

        os.system("del /s %s\*.tmp" % public.to_path(soft_path))

        try:
            os.remove(temp)
        except :pass

        try:
            
            shutil.rmtree(local_tmp)
        except :pass

        return True


    def update_net(self,soft_path, version):
        """
        更新指定.net版本软件
        @soft_path 软件路径
        @version = public.get_net_version()
        """
        src_path = '{}/{}'.format(soft_path,version)
        os.system("echo f|xcopy /s /c /e /y /r {} {}".format(public.to_path(src_path),public.to_path(soft_path)))

        return True

    def uninstall(self,name):
        """
        卸载插件
        @插件名称
        """
        if public.get_server_status(name) >= 0: public.delete_server(name)
        try:
            plugin_path = panelPath + '/plugin/' + name
            if os.path.exists(plugin_path):                
                for filename in os.listdir(plugin_path):
                    if filename[-4:] == '.pyd':
                        local_name = plugin_path + '/' + filename
                        sfile = os.path.basename(local_name)
                        os.rename(local_name,local_name.replace(sfile,'{}.pyc'.format(public.GetRandomString(8))))                        

            shutil.rmtree(plugin_path)
        except :pass

        try:
            soft_path = panelSetup + '/' + name
            shutil.rmtree(soft_path)
        except :pass

        return True
