#coding:utf-8
import base64
import urllib
import urllib2
from userInfoConfFile.userInfoConf import UserInfoConfFile
from logger.logrecord import LogRecord
import re
import time
import os
import json
import logging
import logger

class LogUpLoad:
    """
    日志上传类，可以上传日志压缩文件和分段上传原始日志文件
    """
    isUploading=False
    def __init__(self):
        self.__sectionLength=100000#单个文件分段的大小
        self.__conf=UserInfoConfFile()
        self.__logUrl=r'/api/terminals/logUpload/linux/'
        self.__fileName=r'dv_client'
        self.__folderName=r'linux_client'
        self.__center='192.168.102.33:8080'
        self.__logPath=r'/mcos/dvclient/log/'
        self.logNo=""

    def isValidIP_Port(self,ip_port):
        """
        判断平台设置是否是正确的网络格式
        :param ip_port: 平台的ip和端口
        :return:格式是否正确
        """
        reg=re.compile('^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-4]):([1-9]\\d{0,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d\\d|655[0-2]\\d|6553[0-5])$')
        if not re.match(reg,ip_port):
            return False
        return True

    def getCenter(self):
        """
        获取默认平台的ip和端口
        :return:
        """
        try:
            self.__center=self.__conf.getDefaultCenter()
            if self.__center.find(':') >= 0:
                if self.isValidIP_Port(self.__center):
                    return True
        except Exception,err:
            LogRecord.instance().logger.exception("上传日志，获取默认平台失败！")
        self.__center = ""
        return False

    def startUpload(self,isPressed=False):
        """
        执行具体的文件上传工作
        :param isPressed: 是否上传压缩格式的文件
        :return:上传日志文件是否成功
        """
        if LogUpLoad.isUploading:
            return False
        else:
            LogUpLoad.isUploading=True
        url='http://'
        if not self.getCenter():
            LogRecord.instance().logger.warn("获取默认平台失败，无法上传日志！")
            LogUpLoad.isUploading=False
            return False
        url+=self.__center
        url+=self.__logUrl
        if not isPressed:
            url+=self.__fileName+r'/log'
            if not self.uploadFile(url,'%sdv_client.log'%self.__logPath):
                LogUpLoad.isUploading=False
                return False
        else:
            url+=self.__folderName+r'/tar.gz'
            try:
                if os.path.exists('%slinux_client.tar.gz'%self.__logPath):
                    try:
                        os.remove('%slinux_client.tar.gz'%self.__logPath)
                    except Exception,err:
                        LogRecord.instance().logger.exception("删除同名压缩文件异常！")
                        LogUpLoad.isUploading=False
                        return False
                LogRecord.instance().logger.debug("压缩文件，关闭日志输出！")
                originLevel=LogRecord.instance().logger.getEffectiveLevel()
                LogRecord.instance().logger.setLevel(logging.CRITICAL)
                result=os.popen('cd %s \n'%self.__logPath+'sudo tar -czf linux_client.tar.gz *.log*')
                result.close()
                LogRecord.instance().logger.setLevel(originLevel)
                LogRecord.instance().logger.debug("压缩文件完成，开启日志输出！")
            except Exception,err:
                LogRecord.instance().logger.exception("压缩文件失败！")
            try:
                if(not os.path.exists('%slinux_client.tar.gz'%self.__logPath)):
                    LogRecord.instance().logger.warn("压缩文件超时，上传压缩文件上传失败，退出！")
                    LogUpLoad.isUploading=False
                    return False
                if not self.uploadGZ(url,'%slinux_client.tar.gz'%self.__logPath):
                    try:
                        os.remove('%slinux_client.tar.gz'%self.__logPath)
                    except Exception,err:
                        LogRecord.instance().logger.exception("上传压缩文件失败，删除压缩文件异常！")
                    LogUpLoad.isUploading=False
                    return False
                LogRecord.instance().logger.debug("完成日志上传！")
            except Exception,err:
                LogRecord.instance().logger.exception("上传压缩包文件失败！")
                LogUpLoad.isUploading=False
                return False
            finally:
                try:
                    os.remove('%slinux_client.tar.gz'%self.__logPath)
                except Exception,err:
                    LogRecord.instance().logger.exception("删除压缩文件异常！")
        LogUpLoad.isUploading=False
        return True

    def uploading(self,url,logData):
        """
        单次上传请求
        :param url: 上传日志的网络请求地址
        :param logData: 字符串格式的日志文件内容
        :return:是否上传成功
        """
        try:
            fData64=base64.encodestring(logData)

            response=urllib2.urlopen(url,fData64)
            the_page = response.read()
            try:
                result=json.loads(the_page)
                if result["result"]["status"] == "y":
                    self.logNo=str(result["result"]["info"])
                    LogRecord.instance().logger.info("上传文件返回的info："+self.logNo)
                    return True
            except Exception,err:
                LogRecord.instance().logger.exception("上传文件返回值异常！")
        except Exception,err:
            LogRecord.instance().logger.exception("上传文件失败！")
        return False

    def uploadFile(self,url,fileName):
        """
        分段上传原始日志文件
        :param url: 上传日志文件的网络请求地址
        :param fileName: 上传的日志文件名
        :return:是否上传成功
        """
        try:
            fSize=os.path.getsize(fileName)
            f=open(fileName,'r')
            i=0
            fHead=''
            while i*self.__sectionLength <= fSize:
                print i,fSize
                fStr=f.read(self.__sectionLength)
                fStr=fHead+fStr
                if (fStr[-1] != '\n') and ((i-1)*self.__sectionLength <= fSize):
                    itmp=fStr.rfind('\n')
                    fHead=fStr[itmp+1:]
                    fStr=fStr[:itmp+1]
                else:
                    fHead=''
                if not self.uploading(url,fStr):
                    LogRecord.instance().logger.error("上传文件失败，中断文件上传！")
                    return False
                i+=1
        except Exception,err:
            LogRecord.instance().logger.exception("上传文件失败！")
            return False
        return True

    def uploadGZ(self,url,fileName):
        """
        上传压缩格式日志文件
        :param url: 上传日志文件的网络请求地址
        :param fileName: 上传的文件名
        :return:是否上传成功
        """
        try:
            fSize=os.path.getsize(fileName)
            f=open(fileName,'rb')
            fStr=f.read(fSize)
            if not self.uploading(url,fStr):
                LogRecord.instance().logger.error("上传文件失败，中断文件上传！")
                return False
        except Exception,err:
            LogRecord.instance().logger.exception("上传文件失败！")
            return False
        return True


if __name__ == "__main__":
    upload=LogUpLoad()
    upload.startUpload(True)
