#!/usr/bin/python
#_*_ coding:utf-8 _*_

import MySQLdb
import time
import threading
import random
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Utils, Encoders
import mimetypes
import sys
import smtplib
import socket
import getopt
import os
import re
import shutil
import platform

'''
后端处理脚本:封装了“邮件处理类”和“任务类”。其中“任务类”对应DB,“内部类”对应TABLE

主要完成:
1、定时查询任务
2、标记DB状态
3、判断任务执行、并标记任务
4、形成日常处理日志
5、错误日志上报
6、任务守护
7、任务编号带入SourceCode,工模显示任务编号
8、兼容上海/深圳部署

注意:
    先构造类的实例“__init__”,在进行方法调用
    调试模式下,辅助调试方法“__str__()”
    统一的“config()”接口,对TABLE进行处理,不允许有其它接口
'''

g_daemonMode = 0
g_nullDo = False

#单次任务处理类,对应主表Compile
class CTask:
    def __init__(self,data):
        listIr = str(data[5]).split(",")
        listIr.append(u"IRKK")
        self.compileId = data[0]
        self.userName = data[1]
        self.userMail = data[2]
        self.boardName = data[3]
        self.panelName = data[4]
        self.irName = set(listIr)
        self.contentId = data[6]
        self.complieDate = data[7]
        self.binFile = data[8]
        self.compileState = data[9]
        self.sourcePath = "/kitking/xxx/webSourceCode"       #默认的编译目录
        self.webPath = "/var/www/web"                                   #默认的WEB目录
        self.webErrorMail = "xxxd@163.com"                 #错误日志上报
        self.dbSource = ["ATV","CVBS","YPBPR","PC","HDMI","MULTIMEDIS"]
        if list(platform.uname())[2] == "3.16.0-23-generic":            #深圳服务器更改部署路径
            self.sourcePath = "/kk/xxx/share/webSourceCode"

    class CContent:
        def __init__(self,data):
            self.contentID = data[0]
            self.area = data[1]
            self.theme = data[2]
            self.panelID = data[3]
            self.language = set(str(data[4]+","+data[5]).split(","))
            self.deLanguage = data[5]
            self.keypadName = data[6]
            self.logoName = data[7]
            self.pqName = data[8]
            self.speaker = data[9]
            self.source = data[10]
            self.powerState = data[11]
            self.swArc = data[12]
            self.swCec = data[13]
            self.swMhl = data[14]
            self.swOsdgame = data[15]
            self.swNes = data[16]
            self.swBt = data[17]
            self.swCaptureLogo = data[18]
            self.swBlueScreen = data[19]
            self.blstyle = [20]

        def info(self):
            return [self.contentID,self.area,self.theme,self.language,self.keypadName,self.logoName]

        def __str__(self):
            return ("contentID[%d]-[%s]-[%s]-[%s]-[%s]-[%s]-arc[%s]-cec[%s]-mhl[%s]-osdgame[%s]" %(self.contentID,self.area,self.theme,self.language,self.keypadName,self.logoName,self.swArc,self.swCec,self.swMhl,self.swOsdgame)).encode("utf-8")

        def config(self,strPath):
            listPro = []
            # 修改主题 /CEC/ARC/OSDGAME/抓图
            with open(strPath + '/menuconfig.config',"r") as mFile:
                listTemp = mFile.readlines()
            for each in listTemp:
                if "CONFIG_TV_NEW_UI" in each:
                    if self.theme == u"MSTAR风格":
                        each = "# CONFIG_TV_NEW_UI is not set\n"
                    elif self.theme == u"蓝色经典":
                        each = "CONFIG_TV_NEW_UI=y\n"
                elif "CONFIG_SUPPORT_CAI_UI_STYLE" in each:
                    if self.theme == u"MSTAR风格":
                        each = "#CONFIG_SUPPORT_CAI_UI_STYLE is not set\n"
                    elif self.theme == u"简约风格":
                        each = "CONFIG_SUPPORT_CAI_UI_STYLE=y\n"
                elif "CONFIG_SUPPORT_MSTAR_UI_STYLE" in each:
                    if self.theme == u"MSTAR风格":
                        each = "CONFIG_SUPPORT_MSTAR_UI_STYLE=y\n"
                    elif self.theme == u"简约风格":
                        each = "# CONFIG_SUPPORT_MSTAR_UI_STYLE is not set\n"
                elif "CONFIG_SUPPORT_KK_SIMPLIFIED_CHINESE" in each:
                    each = "# CONFIG_SUPPORT_KK_SIMPLIFIED_CHINESE is not set\n"
                elif "CONFIG_SUPPORT_OSDLANGUAGE_KOREAN" in each:
                    if "Korean" in self.language:
                        each = "CONFIG_SUPPORT_OSDLANGUAGE_KOREAN=y\n"
                    else:
                        each = "# CONFIG_SUPPORT_OSDLANGUAGE_KOREAN is not set\n"
                elif "CONFIG_SUPPORT_CEC_TV" in each:
                    if "NONE" in self.swCec:
                        each = "# CONFIG_SUPPORT_CEC_TV is not set\n"
                    else:
                        each = "CONFIG_SUPPORT_CEC_TV=y\nCONFIG_SUPPORT_ARC=y\n"
                elif "CONFIG_OSDGAME_BOXMAN_SUPPORT" in each:
                    if "NONE" in self.swOsdgame:
                        each = "# CONFIG_OSDGAME_BOXMAN_SUPPORT is not set\n"
                    else:
                        each = "CONFIG_OSDGAME_BOXMAN_SUPPORT=y\n"
                elif "CONFIG_OSDGAME_HITRAT_SUPPORT" in each:
                    if "NONE" in self.swOsdgame:
                        each = "# CONFIG_OSDGAME_HITRAT_SUPPORT is not set\n"
                    else:
                        each = "CONFIG_OSDGAME_HITRAT_SUPPORT=y\n"
                elif "CONFIG_OSDGAME_GOBANG_SUPPORT" in each:
                    if "NONE" in self.swOsdgame:
                        each = "# CONFIG_OSDGAME_GOBANG_SUPPORT is not set\n"
                    else:
                        each = "CONFIG_OSDGAME_GOBANG_SUPPORT=y\n"
                elif "CONFIG_OSDGAME_TETRIS_SUPPORT" in each:
                    if "NONE" in self.swOsdgame:
                        each = "# CONFIG_OSDGAME_TETRIS_SUPPORT is not set\n"
                    else:
                        each = "CONFIG_OSDGAME_TETRIS_SUPPORT=y\n"
                elif "CONFIG_OSDGAME_SUDOKU_SUPPORT" in each:
                    if "NONE" in self.swOsdgame:
                        each = "# CONFIG_OSDGAME_SUDOKU_SUPPORT is not set\n"
                    else:
                        each = "CONFIG_OSDGAME_SUDOKU_SUPPORT=y\nCONFIG_OSD_GAME_SUPPORT=y\n"
                elif "CONFIG_SUPPORT_TTX" in each:
                    if u"亚太" in self.area:
                        each = "# CONFIG_SUPPORT_TTX is not set\n"
                    else:
                        each = "CONFIG_SUPPORT_TTX=y\nCONFIG_TTX_BYPASS_MODE=y\nCONFIG_TT15_SUPPORT=y\nCONFIG_TTX_FONT_SIZE_30=y\nCONFIG_SUPPORT_ATS=y\n"
                elif "CONFIG_SUPPORT_CAPTURE_LOGO" in each:
                    if "NONE" in self.swCaptureLogo:
                        each = "# CONFIG_SUPPORT_CAPTURE_LOGO is not set\n"
                    else:
                        each = "CONFIG_SUPPORT_CAPTURE_LOGO=y\nCONFIG_CAPTURE_LOGO_MAX_SIZE=\"80\"\n"
                listPro.append(each)
            with open(strPath + '/menuconfig.config',"w") as mFile:
                mFile.writelines(listPro)

            listPro = []
            if "OFF" in self.swBlueScreen:
                listPro.append("#define WWW_BLUSCREEN  0\n\n")
            else:
                listPro.append("#define WWW_BLUSCREEN  1\n\n")
            #此处创建web_www.h,后面的PQ为追加方式
            with open(strPath+"/aps/include/web_www.h","w") as mFile:
                mFile.writelines(listPro)

            # 修改语言  通道
            listTemp = []
            listPro = []
            with open(strPath+'/aps/customer/radisson/sub_customer/RAD_radisson/radisson/subcustomer_setting.h',"r") as mFile:
                listTemp = mFile.readlines()

            for each in listTemp:
                pat = re.compile(".*DEFAULT_SUPPORT_OSD_LANGUAGE_(\w*?)\s+.*")
                if pat.search(each):
                    if pat.search(each).group(1) in self.language:
                        each = "#define DEFAULT_SUPPORT_OSD_LANGUAGE_%s    1\n" % (pat.search(each).group(1))
                    else:
                        each = "#define DEFAULT_SUPPORT_OSD_LANGUAGE_%s    0\n" % (pat.search(each).group(1))
                elif "DEFAULT_CURRENT_LANGUAGE" in each:
                    each = "#define DEFAULT_CURRENT_LANGUAGE   APP_OSDLANG_%s\n" % self.deLanguage.upper()
                elif "DEFAULT_SUPPORT_SOURCE_TYPE_AV2" in each:
                    if "AV2" in self.source:
                        each = "#define DEFAULT_SUPPORT_SOURCE_TYPE_AV2             1\n"
                    else:
                        each = "#define DEFAULT_SUPPORT_SOURCE_TYPE_AV2             0\n"
                elif re.search(".*DEFAULT_SUPPORT_SOURCE_TYPE_YPBPR[^\d].*",each):
                    if "YPBPR" in self.source:
                        each = "#define DEFAULT_SUPPORT_SOURCE_TYPE_YPBPR             1\n"
                    else:
                        each = "#define DEFAULT_SUPPORT_SOURCE_TYPE_YPBPR             0\n"
                listPro.append(each)
            with open(strPath + '/aps/customer/radisson/sub_customer/RAD_radisson/radisson/subcustomer_setting.h',"w") as mFile:
                mFile.writelines(listPro)
            # 功放 开机状态
            listTemp = []
            with open(strPath + "/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","r") as mFile:
                listFile = mFile.readlines()
                for each in listFile:
                    if "DEFAULT_AMP_POWER" in each:
                        each = "#define DEFAULT_AMP_POWER    %s\n" %(self.speaker)
                    elif "DEFAULT_AC_AUTO_POWERON_STATUS" in each:
                        each = "#define DEFAULT_AC_AUTO_POWERON_STATUS      AC_AUTO_%s\n" %(self.powerState)

                    listTemp.append(each)
            with open(strPath + "/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","w") as mFile:
                mFile.writelines(listTemp)

    class CPanel:
        def __init__(self,data):
            self.panelID = data[0]
            self.panelName = data[1]
            self.reverse = data[2]
            self.pwm = data[3]
            self.mA = data[4]
            self.deValue = data[5]
            self.lvdsMap = data[6]
            self.freeRun = data[7]

        def __str__(self):
            return "Panel[%s]-reverse[%s]-pwm[%s]-mA[%s]-deValue[%s]-lvdsMap[%s]-freeRun[%s]" %(self.panelName,self.reverse,self.pwm,self.mA,self.deValue,self.lvdsMap,self.freeRun)

        def config(self,strPath):
            listPro = []
            #修改倒屏
            with open(strPath+"/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","r") as mFile:
                listTemp = mFile.readlines()
                for each in listTemp:
                    if "PANEL_INVERT" in each:
                        each = "#define PANEL_INVERT    %d\n" % (1 if self.reverse == "ON" else 0)
                    listPro.append(each)

            with open(strPath+"/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","w") as mFile:
                mFile.writelines(listPro)

            listPro = []
            #修改FREEFUN/LVDSMAP
            with open(strPath+"/aps/customer/radisson/public/panel/%s/panel_setting.h" % self.panelName,"r") as mFile:
                listTemp = mFile.readlines()
                for each in listTemp:
                    if "PANEL_INTERFACE" in each:
                        each = "#define PANEL_INTERFACE    %d\n" %(1 if self.freeRun == "ON" else 0)
                    elif "PANEL_LVDS_TYPE" in each:
                        if self.lvdsMap == "JEIDA":
                            each = "#define PANEL_LVDS_TYPE    0\n"
                        elif self.lvdsMap == "VESA(LSB)":
                            each = "#define PANEL_LVDS_TYPE    1\n"
                        elif self.lvdsMap == "VESA(MSB)":
                            each = "#define PANEL_LVDS_TYPE    2\n"
                    listPro.append(each)

            with open(strPath+"/aps/customer/radisson/public/panel/%s/panel_setting.h" % self.panelName,"w") as mFile:
                mFile.writelines(listPro)

            #修改LED背灯电流
            listPro = []
            with open(strPath + "/menuconfig.config", "r") as mFile:
                listTemp = mFile.readlines()
            for each in listTemp:
                if "CONFIG_INPUT_CURRENT_BL" in each:
                    each = "CONFIG_INPUT_CURRENT_BL=%s\n" % self.mA
                listPro.append(each)
            with open(strPath + "/menuconfig.config", "w") as mFile:
                mFile.writelines(listPro)

    class CKeypad:
        def __init__(self,data):
            self.keypadName = data[0]
            self.keyType = data[1]
            self.k0 = data[2]
            self.k1 = data[3]
            self.k2 = data[4]
            self.k3 = data[5]
            self.k4 = data[6]
            self.k5 = data[7]
            self.k6 = data[8]
            self.k7 = data[9]
            self.data = data

        def __str__(self):
            return ("keypadName[%s]-[%s]-[%s]-[%s]-[%s]-[%s]-[%s]-[%s]-[%s]-[%s]" %(self.keypadName,self.keyType,self.k0,self.k1,self.k2,self.k3,self.k4,self.k5,self.k6,self.k7)).encode("utf-8")

        def config(self,strPath,strBoard):
            keypadPath = strPath + "/aps/customer/radisson/%s/adaptable/keypad_mapping_table.c" %strBoard
            with open(keypadPath, "r") as mFile:
                listTemp = mFile.readlines()
            listPro = []
            listTemp1 = []
            bWebMark = False
            mapKey = {
                "POWER": "POWER",
                "MENU": "MENU",
                "SOURCE": "SOURCE",
                "CH+": "UP",
                "CH-": "DOWN",
                "VOL+": "RIGHT",
                "VOL-": "LEFT",
                "NULL":"MAX"
            }
            for each in listTemp:
                if "WWW" in each:
                    bWebMark = True
                    listPro.append(each)
                    continue

                if bWebMark:
                    listTemp1.append(each)
                else:
                    listPro.append(each)

            lineNumber = 0
            keyDataNumber = 2
            ADC0_POWER_ON_KEY = 0x01
            for each in listTemp1:
                if "#" in each:
                    break
                pat = re.compile("(.*\{\s*\d+,+\s*(.*?),+\s*)UI_EVENT_KEYPAD_(\w*).*")
                if pat.search(each):
                    if "POWER" in mapKey[self.data[keyDataNumber]]:
                        ADC0_POWER_ON_KEY = pat.search(each).group(2)
                    listTemp1[lineNumber] = pat.search(each).group(1)+"UI_EVENT_KEYPAD_%s  },\n" %(mapKey[self.data[keyDataNumber]])
                    keyDataNumber = keyDataNumber+1
                lineNumber = lineNumber + 1
            listPro = listPro+listTemp1
            with open(keypadPath, "w") as mFile:
                mFile.writelines(listPro)

            #修改POWER键
            listPro = []
            listTemp = []
            keypadPath = strPath + "/aps/customer/radisson/%s/adaptable/keypad_mapping_table.h" % strBoard
            with open(keypadPath, "r") as mFile:
                listTemp = mFile.readlines()
            for each in listTemp:
                if "KEYPAD_PWR_ON_KEY" in each:
                    each = "#define    KEYPAD_PWR_ON_KEY    (ADC1_POWER_ON_KEY|%s)\n" %(ADC0_POWER_ON_KEY)
                listPro.append(each)
            with open(keypadPath, "w") as mFile:
                mFile.writelines(listPro)

    class CLogo:
        def __init__(self,data):
            self.logoID = data[0]
            self.userName = data[1]
            self.logoName = data[2]
            self.logoType = data[3]
            self.logoDate = data[4]
            self.logoFile = data[5]

        def __str__(self):
            return ("Logo[%d]-userName[%s]-logoName[%s]-logoType[%s]" %(self.logoID,self.userName,self.logoName,self.logoType)).encode("utf-8")

        def config(self,strPath):
            listTemp = []
            if len(self.logoFile):
                with open(strPath + "/aps/customer/radisson/sub_customer/RAD_radisson/radisson/logo/title_logo.jpg","wb") as mFile:
                    mFile.write(self.logoFile)
            with open(strPath + "/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","r") as mFile:
                listFile = mFile.readlines()
                for each in listFile:
                    if "DEFAULT_POWER_SHOW_LOGO" in each:
                        if len(self.logoFile):
                            each = "#define DEFAULT_POWER_SHOW_LOGO    POWER_SHOW_LOGO\n"
                        else:
                            each = "#define DEFAULT_POWER_SHOW_LOGO    POWER_HIDE_LOGO\n"
                        listTemp.append(each)
                    else:
                        listTemp.append(each)
            with open(strPath + "/aps/customer/radisson/sub_customer/RAD_radisson/radisson/boot_setting.h","w") as mFile:
                mFile.writelines(listTemp)

    class CPq:
        def __init__(self,data):
            self.pqName = data[0]
            self.pqData = data[1].split(",")

        def __str__(self):
            return ("pqName[%s]" %(self.pqName)).encode("utf-8")

        def config(self,strPath,dbSource):
            listPro = []
            for i in range(len(dbSource)):
                strData = "#define COLOR_TEMP_TYPE_%s_WWW    " %(dbSource[i])
                for j in range(3):
                    strData += "{" + ','.join(self.pqData[i*18+j*6:i*18+j*6+6]) + "},"
                strData += "\n"
                listPro.append(strData)
            listCurve = self.pqData[len(dbSource)*18:]
            for i in range(len(dbSource)):
                strData = "#define CURVE_TYPE_%s_WWW    " %(dbSource[i])
                for j in range(5):
                    strData += "{" + ','.join(listCurve[i*25+j*5:i*25+j*5+5]) + "},"
                strData += "\n"
                listPro.append(strData)
            listPro.append("\n\n")
            #content table增加了蓝屏,此处为追加方式
            with open(strPath+"/aps/include/web_www.h","a") as mFile:
                mFile.writelines(listPro)

    def config(self):
        listPro = []
        #配置mconfig
        # 板型 屏参 遥控
        listPro.append('CONFIG_CUSTOMER_NAME="radisson"\n')
        listPro.append('CONFIG_SUBCUSTOMER_NAME="RAD_radisson"\n')
        listPro.append('CONFIG_SUBSUBCUSTOMER_NAME="radisson"\n')
        if self.tContent.theme == u"蓝色经典":
            listPro.append('CONFIG_APP_FOLDER_NAME="formal"\n')
            listPro.append('CONFIG_PROJECT_NAME="%s___formal___ATV"\n' % self.boardName)

        else:
            listPro.append('CONFIG_APP_FOLDER_NAME="atv_project"\n')
            listPro.append('CONFIG_PROJECT_NAME="%s___atv_project___ATV"\n' % self.boardName)

        #根据数据库配置  板型  屏参
        listPro.append('CONFIG_MODEL_BOARD_NAME="%s"\n' % self.boardName)
        listPro.append("CONFIG_PANEL_TYPE_=\"%s\"\n" % (self.panelName))
        listPro.append("CONFIG_PANEL_TYPE_DEFAULT_FOLDER=\"%s\"\n" % self.panelName)

        #设置默认的EDID
        pat = re.compile(".*?_(\d+)[xX](\d+)")
        if pat.search(self.panelName):
            listPro.append("CONFIG_DDC_DeafaultTable_%sx%s=y\n" % (pat.search(self.panelName).group(1), pat.search(self.panelName).group(2)))

        for each in set(self.irName):
            listPro.append("CONFIG_%s=y\n" % (each))

        with open(self.sourcePath + "/mconfig.config", "w") as mFile:
            mFile.writelines(listPro)

        #拷贝menuconfig boardconfig
        if os.path.exists(self.webPath + '/scripts/menuconfig.config'):
            shutil.copy(self.webPath + '/scripts/menuconfig.config', self.sourcePath + '/menuconfig.config')

        boardConfigPath = self.sourcePath + '/aps/customer/radisson/%s/boardconfig.config' %(self.boardName)
        print boardConfigPath
        if os.path.exists(boardConfigPath):
            shutil.copy(boardConfigPath, self.sourcePath + '/boardconfig.config')

    def info(self):
        return [self.compileId,self.userName,self.boardName,self.panelName,self.irName,self.contentId,self.complieDate,self.compileState]

    def __str__(self):
        return ("compileId[%d]-[%s]-[%s]-[%s]-[%s]-[%d]" %(self.compileId,self.userName,self.boardName,self.panelName,self.irName,self.contentId)).encode("utf-8")

    def log(self):
        #创建实例后才能调用
        printLog(self)
        printLog(self.tContent)
        printLog(self.tPanel)
        printLog(self.tLogo)
        printLog(self.tKeypad)
        printLog(self.tPq)

    def sendMail(self):
        listDir = os.listdir(self.sourcePath + "/mergedir")
        listBinFile = [x for x in listDir if "RR8501" in x]
        mail = CSendMail()
        strIr = ""
        for strEach in self.irName:
            strIr = strIr + " " + strEach
        strTitle = '[WEB][%s][%s][%s][%s]' % (self.userName, self.boardName,self.panelName,strIr)
        if len(listBinFile):
            # 编译完成,发送邮件
            if g_nullDo == False:
                ret = mail.send(mail.username, self.userMail, strTitle, u"    感谢您对我们公司的支持,如果有问题请及时与我们联系!", self.sourcePath + "/mergedir/" + listBinFile[0])
                # if ret != 'OK':
                # printLog ret
                # sys.exit(4)
                # else:
                # printLog "Mail %s send ok" %(toAddress)
        else:
            ret = mail.send(mail.username, self.webErrorMail, strTitle+" Compile Error", u"    编译错误请尽快查看!")

    def genTableInstance(self,cur):
        sql = 'select * from Content where contentID=(select contentID from Compile where compileID=%d)' % self.compileId
        cur.execute(sql)
        data = cur.fetchone()
        self.tContent = self.CContent(data)

        sql = 'select * from Panel where panelID = %d' % self.tContent.panelID
        cur.execute(sql)
        data = cur.fetchone()
        self.tPanel = self.CPanel(data)

        sql = 'select * from Logo where logoName = "%s"' % self.tContent.logoName
        cur.execute(sql)
        data = cur.fetchone()
        self.tLogo = self.CLogo(data)

        sql = 'select * from Keypad where keypadName = "%s"' % self.tContent.keypadName
        cur.execute(sql)
        data = cur.fetchone()
        self.tKeypad = self.CKeypad(data)

        sql = 'select * from PQ where pqName = "%s"' % self.tContent.pqName
        cur.execute(sql)
        data = cur.fetchone()
        self.tPq = self.CPq(data)

        self.log()

    def compile(self):
        if g_nullDo == False:
            os.system('cd %s; make WWW=%d clean &> /dev/null; make WWW=%d -j &> /dev/null' % (self.sourcePath,self.compileId,self.compileId))
            #os.system('cd %s; make clean&> /dev/null; make -j' % (self.sourcePath))

    def finishTask(self,cur):
        # 更新任务标记
        if g_nullDo == True:
            return
        listDir = os.listdir(self.sourcePath + "/mergedir")
        listBinFile = [x for x in listDir if "RR8501" in x]

        #编译不通过,再有一次编译机会
        if len(listBinFile) == 0:
            self.compile()
            listDir = os.listdir(self.sourcePath + "/mergedir")
            listBinFile = [x for x in listDir if "RR8501" in x]

        if len(listBinFile):
            with open(self.sourcePath + "/mergedir/" + listBinFile[0], "rb") as mFile:
                bin = mFile.read()
            strSql = 'update Compile set binFile=%s where compileID=%s'
            param = ((MySQLdb.Binary(bin)), self.compileId)
            cur.execute(strSql, param)
            cur.execute('update Compile set compileState=1 where compileID=%s', self.compileId)
            os.system('cd %s; make clean &> /dev/null' % (self.sourcePath))          #编译后清楚BIN文件,不能省略
            #self.inform(True)
        else:
            cur.execute('update Compile set compileState=2 where compileID=%s', self.compileId)
            printLog("---------------->error<----------------")
            #self.inform(False)

    def handle(self,cur):
        self.genTableInstance(cur)

        if os.path.exists(self.sourcePath):
            self.config()                                       # Compile Table 生成mconfig menuconfig 板型 屏参 遥控
            self.tContent.config(self.sourcePath)               # Content Table
            self.tPanel.config(self.sourcePath)                 # Panel Table
            self.tLogo.config(self.sourcePath)                  # LOGO Talbe
            self.tKeypad.config(self.sourcePath,self.boardName) # Keypad Table
            self.tPq.config(self.sourcePath,self.dbSource)      # PQ Table
            self.compile()                                      # 编译 CODE
            self.sendMail()                                     # 发送邮件
            self.finishTask(cur)                                # 更新任务标记  上传文件

class CSendMail:
    def __init__(self, smtpServer="smtp.163.com", username="henry_rad@163.com", password="radisson123"):
        #rad_radisson@163.com     pwdradisson
        self.smtpServer = smtpServer
        self.username = username
        self.password = password

    def genMsgInfo(self, fromAddress, toAddress, subject, content, fileList, \
                   subtype='plain', charset='gb2312'):

        msg = MIMEMultipart()
        msg['From'] = fromAddress
        msg['To'] = toAddress
        msg['Date'] = Utils.formatdate(localtime=1)
        msg['Message-ID'] = Utils.make_msgid()

        # 标题
        if subject:
            msg['Subject'] = subject

        # 内容
        if content:
            body = MIMEText(content, subtype, charset)
            msg.attach(body)

        # 附件
        if fileList:
            listArr = fileList.split(',')
            for item in listArr:

                # 文件是否存在
                if os.path.isfile(item) == False:
                    continue

                att = MIMEText(open(item).read(), 'base64', 'gb2312')
                att["Content-Type"] = 'application/octet-stream'
                # 这里的filename邮件中显示什么名字
                filename = os.path.basename(item)
                att["Content-Disposition"] = 'attachment; filename=' + filename
                msg.attach(att)

        return msg.as_string()

    def send(self, fromAddress, toAddress, subject=None, content=None, fileList=None, \
             subtype='plain', charset='gb2312'):

        try:
            server = smtplib.SMTP(self.smtpServer)

            # 登录
            try:
                server.login(self.username, self.password)
            except smtplib.SMTPException, e:
                return "ERROR:Authentication failed:", e

            # 发送邮件
            server.sendmail(fromAddress, toAddress.split(',') \
                            , self.genMsgInfo(fromAddress, toAddress, subject, content, fileList, subtype, charset))

            # 退出
            server.quit()
        except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
            return "ERROR:Your mail send failed!", e

        return 'OK'

def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
    try:
        pid = os.fork()
        # 父进程(会话组头领进程)退出,这意味着一个非会话组头领进程永远不能重新获得控制终端。
        if pid > 0:
            sys.exit(0)  # 父进程退出
    except OSError, e:
        sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)

        # 从父进程脱离
    os.chdir("/")  # chdir确认进程不保持任何目录于使用状态,否则不能umount一个文件系统。也可以改变到对于守护程序运行重要的文件所在目录
    os.umask(0)  # 调用umask(0)以便拥有对于写的任何东西的完全控制,因为有时不知道继承了什么样的umask。
    os.setsid()  # setsid调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。

    # 执行第二次fork
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)  # 第二个父进程退出
    except OSError, e:
        sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)

        # 进程已经是守护进程了,重定向标准文件描述符

    for f in sys.stdout, sys.stderr: f.flush()
    si = open(stdin, 'r')
    so = open(stdout, 'a+')
    se = open(stderr, 'a+', 0)
    os.dup2(si.fileno(), sys.stdin.fileno())  # dup2函数原子化关闭和复制文件描述符
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

def fun_parse_InputParam():
    global g_daemonMode
    global g_nullDo
    global g_bTestMode

    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hdnt')
    except getopt.GetoptError, err:
        #print str(err)
        sys.exit()

    for op, value in opts:
        if op == "-d":
            g_daemonMode = 1
        elif op == "-n":
            g_nullDo = 1
        elif op == "-h":
            sys.exit()
        else:
            printLog("unhandled option")
            sys.exit()

def printLog(data):
    print data
    sys.stdout.flush()

def dbHandle():
    conn = MySQLdb.connect(
        host='localhost',
        port=3306,
        user='root',
        passwd='rad_radisson',
        db='webCompile',
        charset="utf8"
    )

    cur = conn.cursor()
    printLog('Daemon started with pid %d\n' % os.getpid())

    while True:
        cur.execute("select * from Compile where compileState = 0")
        info = cur.fetchall()
        for data in info:
            task = CTask(data)
            task.handle(cur)

        conn.commit()
        if g_daemonMode:
            time.sleep(60)
        else:
            break
    conn.commit()
    cur.close()
    conn.close()

if __name__ == "__main__":
    fun_parse_InputParam()
    if g_daemonMode:
        daemonize('/dev/null', '/tmp/daemon_stdout.log', '/tmp/daemon_error.log')
    dbHandle()