日志下载器

1、因为某些原因,只能看一段时间的日志,所以我就自己搞了个日志下载器,便于开发同学日常查询日志。

2、这个工具麻烦的地方就是在表格中嵌入checkbox、在子线程中通过信号改变主界面的QProgressBar数据、线程加锁的时机。

from threading import Thread
import threading
import time, datetime
from datetime import date
from PySide2.QtWidgets import QApplication, QMessageBox, QTableWidgetItem, QHeaderView, QFileDialog, QProgressBar
from PySide2.QtUiTools import QUiLoader
from PySide2 import QtCore, QtGui
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
from PySide2.QtCore import Signal,QObject
import requests

lock = threading.Lock()
line_line_number = 0

class TencentSdk:
    def __init__(self):
        self.hostname_list = [
            'xxxx'
        ]
        self.hostnameAndfiledir = {}
        self.secret_id = 'xxx'
        self.secret_key = 'xxx'
        self.region = 'xxx'
        self.global_line_number = 0

    def generate(self, obj:str, tt: str) -> dict:
        '''
        生成日志路径,并检查时间格式是否正确
        :param tt:
        :return:
        '''
        time30daysago = (datetime.datetime.now() - datetime.timedelta(+30)).strftime("%Y-%m-%d")
        if tt <= time30daysago:
            QMessageBox.critical(
                obj,
                '错误',
                '所求日志需要大于30天,请联系运维!')
            return 0
        try:
            _year = tt.split('-')[0]
            _month = tt.split('-')[1]
            _day = tt.split('-')[2]
            date(int(_year), int(_month), int(_day))
        except Exception as e:
            QMessageBox.critical(
                obj,
                '错误',
                '请输入正确的时间!')
        else:
            for _hostname in self.hostname_list:
                dd = f'''/xxx/{_hostname}/{_year}{_month}/{_year}{_month}{_day}.tar.gz'''
                self.hostnameAndfiledir[_hostname] = dd
            return self.hostnameAndfiledir

    def downloadobj(self, obj:str, hostname:str, filekey: str, dst_path: str, ms_obj: str):
        '''
        下载文件对象
        :param obj:
        :param hostname:
        :param filekey:
        :param dst_path:
        :param ms_obj:
        :return:
        '''
        global line_line_number

        config = CosConfig(Region=self.region, SecretId=self.secret_id, SecretKey=self.secret_key)
        client = CosS3Client(config)

        try:
            response = client.get_object(
                Bucket='xxx',
                Key=filekey,
            )
            dp = f'''{dst_path}\\{hostname}.tar.gz'''
            response['Body'].get_stream_to_file(dp)

            lock.acquire()  # 下载的时候是多线程的,计数加锁
            line_line_number = line_line_number + 1
            ms_obj.bar_print.emit(obj.downloadprogressBar, line_line_number)
            lock.release()

        except Exception as e:
            return 0
        return 1

    def getObjectState(self, obj:str, filekey: str):
        '''
        获取文件信息
        :param obj:
        :param filekey:
        :return:
        '''
        config = CosConfig(Region=self.region, SecretId=self.secret_id, SecretKey=self.secret_key)
        client = CosS3Client(config)

        try:
            response = client.head_object(
                Bucket='xxx',
                Key=filekey
            )
        except Exception as e:
            return 0 # 文件不存在
        else:
            return response # 文件存在

class MySignals(QObject):
    bar_print = Signal(QProgressBar,int)

class Stats:

    def __init__(self):
        self.ui = QUiLoader().load('2.ui')

        self.ui.window().setWindowTitle('日志下载')
        self.ui.queryButton.clicked.connect(self.QueryFileCounts)
        self.ui.downloadButton.clicked.connect(self.Download)
        self.ui.selectAllButton.clicked.connect(self.SelectAll)
        self.ui.allcancelButton.clicked.connect(self.CancelAll)

        self.ms = MySignals()
        self.ms.bar_print.connect(self.printToBar)

        self.ipWhite = [
            'xxxx'
        ]

    def QueryFileCounts(self):
        '''
        主界面的展示
        :return:
        '''
        time_context = self.ui.timeEdit.text()
        self._hostnameAndfiledir = TencentSdk().generate(self.ui, time_context)

        if self._hostnameAndfiledir == 0: # 日志时间超过30天,存储类型不允许直接下载
            return 0

        outip = requests.get('http://xxxx').text.strip("\"")
        if outip not in self.ipWhite:
            QMessageBox.critical(
                self.ui,
                '错误',
                '请从公司出口访问!')
            return 0

        self.ui.tableWidget.setRowCount(len(self._hostnameAndfiledir))
        self.ui.tableWidget.setColumnCount(3)
        self.ui.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) #设置每列宽度:根据内容调整表格宽度
        self.ui.tableWidget.setHorizontalHeaderLabels(['选择', '文件路径','文件大小'])

        self.ck = [] #checkbox对象
        _row = 0
        for hostname, filename in self._hostnameAndfiledir.items():
            chkBoxItem = QTableWidgetItem()
            chkBoxItem.setText(hostname)
            chkBoxItem.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            chkBoxItem.setCheckState(QtCore.Qt.Unchecked)
            chkBoxItem.setTextAlignment(QtCore.Qt.AlignCenter)

            self.ck.append(chkBoxItem)

            self.ui.tableWidget.setItem(_row, 0, chkBoxItem)
            self.ui.tableWidget.setItem(_row, 1, QTableWidgetItem(filename))
            res = TencentSdk().getObjectState(self.ui, filename)
            if res == 0:
                self.ui.tableWidget.setItem(_row, 2, QTableWidgetItem('文件不存在'))
            else:
                self.ui.tableWidget.setItem(_row, 2, QTableWidgetItem(str(round(int(res['Content-Length'])/1024/1024,2)) + "MB"))

            _row = _row + 1

    def checkCKnum(self):
        '''
        确认被选中的文件数
        :return:
        '''
        cknum = 0
        for _ck in self.ck:
            if _ck.checkState():
                cknum = cknum + 1
        return cknum

    def Download(self):
        '''
        多线程下载线程
        :return:
        '''
        dst_path = self.openFileNameDialog()

        cknum = self.checkCKnum()
        self.ui.downloadprogressBar.setRange(0,cknum)
        line_num = 0
        for _ck in self.ck:
            if _ck.checkState():
                line_num = line_num + 1
                tt = Thread(target=TencentSdk().downloadobj, args=(self.ui, _ck.text(), self._hostnameAndfiledir[_ck.text()], dst_path, self.ms))
                tt.start()

        if line_num == cknum:
            msg = f'''开始下载!'''
            QMessageBox.information(
                self.ui,
                '开始下载',
                msg)


    def SelectAll(self):
        '''
        选择所有
        :return:
        '''
        for _ck in self.ck:
            _ck.setCheckState(QtCore.Qt.Checked)

    def CancelAll(self):
        '''
        取消所有
        :return:
        '''
        for _ck in self.ck:
            _ck.setCheckState(QtCore.Qt.Unchecked)

    def openFileNameDialog(self):
        '''
        选择下载目录
        :return:
        '''
        filePath = QFileDialog.getExistingDirectory(self.ui, "选择存储路径")

        if sys.platform != 'Darwin' and sys.platform != 'Linux':
            filePath = filePath.replace('/', '\\')
        return filePath

    def printToBar(self, obj, line_num):
        '''
        通过信号来设置主线程界面的bar
        :param obj:
        :param line_num:
        :return:
        '''
        self.ui.downloadprogressBar.setValue(line_num)



if __name__ == '__main__':
    app = QApplication([])
    stats = Stats()
    stats.ui.show()
    app.exec_()

 

最后效果差不多是这样的:

 

posted @ 2022-09-30 16:40  JvvYou  阅读(54)  评论(0)    收藏  举报