#!/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()

Python DB的更多相关文章

  1. Python DB API 连接数据库

    Python DB API Mysql,Oracle,SqlServer 不关闭,会浪费资源.

  2. Python DB operation

    mysql http://www.cnblogs.com/zhangzhu/archive/2013/07/04/3172486.html 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目 ...

  3. python DB.fetchall()--获取数据库所有记录列表

    查询到的数据格式为列表: 多个元素的列表:

  4. Python基础+Pythonweb+Python扩展+Python选修四大专题 超强麦子学院Python35G视频教程

    [保持在百度网盘中的, 可以在观看,嘿嘿 内容有点多,要想下载, 回复后就可以查看下载地址,资源收集不易,请好好珍惜] 下载地址:http://www.fu83.cc/ 感觉文章好,可以小手一抖 -- ...

  5. Python_DB_Api

    python DB API 内容 建立连接connection 数据库交互对象cursor 数据库异常类exception 流程 创建connection 获取cursor 执行查询.执行命令.获取数 ...

  6. [Python] 学习笔记之MySQL数据库操作

    1 Python标准数据库接口DB-API介绍 Python标准数据库接口为 Python DB-API,它为开发人员提供了数据库应用编程接口.Python DB-API支持很多种的数据库,你可以选择 ...

  7. Python开源框架

    info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...

  8. python数据库(mysql)操作

    一.软件环境 python环境默认安装了sqlite3,如果需要使用sqlite3我们直接可以在python代码模块的顶部使用import sqlite3来导入该模块.本篇文章我是记录了python操 ...

  9. 【循序渐进学Python】14.数据库的支持

    纯文本只能够实现一些简单有限的功能.如果想要实现自动序列化,也可以使用 shelve 模块和 pickle 模块来实现.但是,如果想要自动的实现数据并发访问,以及更标准,更通用的数据库(databas ...

随机推荐

  1. 20145322何志威《网络对抗》Exp2 后门原理与实践

    基础问题回答 1 例举你能想到的一个后门进入到你系统中的可能方式? 在网上下载盗版软件时捆绑的后门程序. 不小心进入钓鱼网站. 2 例举你知道的后门如何启动起来(win及linux)的方式? Wind ...

  2. Egret引擎开发基础(一)

    显示图片 var batman:egret.Bitmap = new egret.Bitmap( RES.getRes('hexo-huaheshang_png')); batman.x = 0; b ...

  3. [经验分享]SecureCRT导出操作日志 + Notepad自定义语言格式高亮日志文件

    起因及效果展示 最近使用CRT,有些命令会输出很多内容,这时如果你想要得知输出内容是从哪里开始的,很容易被大量的同种颜色的文字搞的晕头转向.如果输入的命令是不同的颜色,这会大大得帮助我们. 所谓的命令 ...

  4. 通过FISH和下一代测序检测肺腺癌ALK基因融合比较

    ALK FISH探针是FDA批准的用于检测肺癌患者中ALK重排的方法,这些患者可能受益于ALK激酶抑制剂.FISH测定在技术上可能具有挑战性并且难以解释.已经有研究者提出以ALK免疫组织化学和下一代测 ...

  5. window.frames && iframe 跨页面通信

    1.定义 frames[]是窗口中所有命名的框架组成的数组.这个数组的每个元素都是一个Window对象,对应于窗口中的一个框架. 2.用法 假设iframe 是一个以存在的 iframe 的 ID 和 ...

  6. Android多个Module统一配置相同jar或库的版本号

    Android Studio多个Module依赖相同的库时对版本号进行统一配置 在Android项目中,一个项目经常会依赖其他的一个甚至多个库文件,在这种依赖的时候最常见的一个错误就是 jar包版本不 ...

  7. log4j日志文件配置

    ### set log levels ### ### debug (打印代码中logger.debug(xx)的信息)> info(打印代码中logger.info(xx)的信息) log4j. ...

  8. 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)

    最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...

  9. 获取div的高度

    1.获取div的文档总高度(必须DOM操作): var scrollHeight=document.getElementById("inner").scrollHeight; // ...

  10. C#读写配置文件Config

    应用程序配置文件是标准的XML文件,XML标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是configuration.我们经 ...