From 9c24f49d79ea4c08af3cfbdc057490ff2c98a45e Mon Sep 17 00:00:00 2001 From: halliday Date: Mon, 20 Nov 2023 21:38:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Changes.txt | 10 +++ MANIFEST.in | 5 ++ bin/_load.py | 27 +++++++ bin/get_system_info.py | 176 +++++++++++++++++++++++++++++++++++++++++ etc/check_config.yml | 7 ++ release.py | 101 +++++++++++++++++++++++ requirements.txt | 1 + setup.py | 32 ++++++++ start_vscode.bat | 6 ++ tox.ini | 46 +++++++++++ 10 files changed, 411 insertions(+) create mode 100644 Changes.txt create mode 100644 MANIFEST.in create mode 100644 bin/_load.py create mode 100644 bin/get_system_info.py create mode 100644 etc/check_config.yml create mode 100644 release.py create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 start_vscode.bat create mode 100644 tox.ini diff --git a/Changes.txt b/Changes.txt new file mode 100644 index 0000000..d313397 --- /dev/null +++ b/Changes.txt @@ -0,0 +1,10 @@ + changes log +====================================== + +------------------------------ +1.0.0 2023-11-20 + +1.第一版已经初步完成 + + +[mh] diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..650a9fe --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,5 @@ +include README.txt +include requirements.txt tox.ini +recursive-include test *.txt *.py +recursive-include *.txt *.py *.tmpl +recursive-include bin *.* diff --git a/bin/_load.py b/bin/_load.py new file mode 100644 index 0000000..d04f15f --- /dev/null +++ b/bin/_load.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +import os +import sys +import site + +# set path +py_dir = os.path.dirname(os.path.realpath(__file__)) + +parent_dir = os.path.dirname(py_dir) + +# print parent_dir +# if os.path.isdir(os.path.join(parent_dir, "delegate")): + # sys.path.append(parent_dir) + +libdir = os.path.join(parent_dir, "lib") +# print libdir +if os.path.isdir(libdir): + old_len = len(sys.path) + new_sys_path = [] + site.addsitedir(libdir) # @UndefinedVariable + for item in sys.path[old_len:]: + new_sys_path.append(item) + sys.path.remove(item) + sys.path[:0] = new_sys_path + +# set cwd +os.chdir(parent_dir) diff --git a/bin/get_system_info.py b/bin/get_system_info.py new file mode 100644 index 0000000..a83b4f5 --- /dev/null +++ b/bin/get_system_info.py @@ -0,0 +1,176 @@ +#!/usr/bin/python3 +import psutil +import smtplib +import os +import argparse + +from datetime import datetime +from pathlib import Path +from email.mime.text import MIMEText +from email.header import Header +from email.mime.multipart import MIMEMultipart + +# 定义公共的部分 +path = Path(__file__) +report_dir = path.parent.parent / "report" +# 初始化目录 +if not report_dir.exists(): + # shutil.rmtree(data_dir) + report_dir.mkdir() +#报告文件 +week=str(datetime.now().isocalendar()[1]) +file_name = "ComputerInfos-week-" + week + ".txt" +file_path = report_dir/file_name + +#发邮件 +def send_mail(): + #发件人 + sender = 'mh@unamail.com' + # 接收邮件,可以发给多人 + receivers = ['mh@unamail.com'] + # 邮件主体 + msg = MIMEMultipart() + #正文 + message = "第{0}周,{1}运行信息检测已完成,详情请查看附件!".format(week,get_IP()) + msg.attach(MIMEText(message, 'plain', _charset="utf-8")) + # 发送者 + msg['From'] = Header(sender, 'utf-8') + # 接收者 + msg['To'] = Header(receivers[0], 'utf-8') + # 主题 + subject = '【长期任务】第{0}周{1}系统运行信息'.format(week,get_IP()) + msg['Subject'] = Header(subject, 'utf-8') + #附件信息 + att = MIMEText(open(str(file_path), 'rb').read(), 'base64', 'utf-8') + att["Content-Type"] = 'application/octet-stream' + att["Content-Disposition"] = 'attachment; filename="{}"'.format(file_name) + msg.attach(att) + + try: + smtpObj = smtplib.SMTP('10.10.110.102') + smtpObj.sendmail(sender, receivers, msg.as_string()) + print ("邮件发送成功") + except smtplib.SMTPException: + print ("Error: 无法发送邮件") + + +#写入文件 +def save_txt(datas): + with open(str(file_path),'a+',encoding='utf-8',newline='') as file_txt: + [file_txt.write(str(item)+'\n') for item in datas] + + +# 获取本机磁盘使用率和剩余空间G信息 +def get_disk_info(): + # 循环磁盘分区 + content = [] + for disk in psutil.disk_partitions(): + # 读写方式 光盘 or 有效磁盘类型 + if 'cdrom' in disk.opts or disk.fstype == '': + continue + disk_name_arr = disk.device.split(':') + disk_name = disk_name_arr[0] + disk_info = psutil.disk_usage(disk.device) + # 磁盘剩余空间,单位G + free_disk_size = disk_info.free//1024//1024//1024 + # 磁盘总空间,单位G + total_disk_size = disk_info.total//1024//1024//1024 + # 当前磁盘使用率、剩余空间G和磁盘总空间信息 + info = " %s盘使用率:%s%%, 剩余空间:%iG, 总大小:%sG" % (disk_name, str(disk_info.percent),free_disk_size,total_disk_size) + # print(info) + # 拼接多个磁盘的信息 + content.append(info) + print(content) + save_txt(content) + +# 获取某个目录的大小 +dir_content=[] +def get_dir_size(path): + list1 = [] + fileList = os.listdir(path) # 获取path目录下所有文件 + for filename in fileList: + pathTmp = os.path.join(path,filename) # 获取path与filename组合后的路径 + if os.path.isdir(pathTmp): # 判断是否为目录 + print("---------------") + dir_content.append(" ---------------") + get_dir_size(pathTmp) # 是目录就继续递归查找 + elif os.path.isfile(pathTmp): # 判断是否为文件 + filesize = os.path.getsize(pathTmp) # 如果是文件,则获取相应文件的大小 + str_tex = ' %s文件的大小为:%d字节' % (pathTmp,filesize) + print(str_tex) + dir_content.append(str_tex) + list1.append(filesize) # 将文件的大小添加到列表 + str_dir_tex = ' %s 目录的大小为: %.4f MB' % (path, (sum(list1)/1024/1024)) + print(str_dir_tex) + dir_content.append(str_dir_tex) + + + +# cpu信息 +def get_cpu_info(): + cpu_percent = psutil.cpu_percent(interval=1) + cpu_info = ["","CPU使用率:%i%%" % cpu_percent,""] + print(cpu_info) + # return cpu_info + save_txt(cpu_info) + +# 内存信息 +def get_memory_info(): + virtual_memory = psutil.virtual_memory() + used_memory = virtual_memory.used/1024/1024/1024 + free_memory = virtual_memory.free/1024/1024/1024 + memory_percent = virtual_memory.percent + memory_info = ["内存使用:%0.2fG,使用率%0.1f%%,剩余内存:%0.2fG" % (used_memory, memory_percent, free_memory),""] + print(memory_info) + # return memory_info + save_txt(memory_info) + + +def get_IP(): + """获取ipv4地址""" + dic = psutil.net_if_addrs() + ipv4_list = [] + for adapter in dic: + snicList = dic[adapter] + for snic in snicList: + # if snic.family.name in {'AF_LINK', 'AF_PACKET'}: + # mac = snic.address + if snic.family.name == 'AF_INET': + ipv4 = snic.address + if ipv4 != '127.0.0.1': + ipv4_list.append(ipv4) + # elif snic.family.name == 'AF_INET6': + # ipv6 = snic.address + print(ipv4_list) + return(ipv4_list[0]) + +def main(): + commoninfo = [] + if not file_path.exists(): + t1 = "本周是第{0}周".format(week) + commoninfo.append(t1) + commoninfo.append("") + commoninfo.append("--------------------START--------------------------") + commoninfo.append("检测时间: {0}".format(datetime.now())) + commoninfo.append("检测IP: {0}".format(get_IP())) + save_txt(commoninfo) + save_txt(["","磁盘使用情况:",""]) + get_disk_info() + get_cpu_info() + get_memory_info() + path = "D:\\agent\\ubackup\\uagent\\logs" + get_dir_size(path) + save_txt(["{0}目录大小:".format(path)]) + save_txt(dir_content) + save_txt(['----------------------END----------------------------']) + + + +if __name__ == '__main__': + main() + #默认不发邮件,通过参数控制 + parser = argparse.ArgumentParser(description='send email') + parser.add_argument("--send-mail", type=bool, default=False) + args = parser.parse_args() + if args.send_mail: + send_mail() diff --git a/etc/check_config.yml b/etc/check_config.yml new file mode 100644 index 0000000..dd2f867 --- /dev/null +++ b/etc/check_config.yml @@ -0,0 +1,7 @@ +#邮箱收件人,支持多个 +receivers: + - "mh@unamail.com" + +#agent安装路径 +agent_dir : "D:\\agent\\ubackup\\uagent\\logs" + diff --git a/release.py b/release.py new file mode 100644 index 0000000..b4f25e7 --- /dev/null +++ b/release.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + create zip 安装包 +""" + +import logging +import os.path +import shutil +import sys + + +def _copytree(src, dst, ignore=None): + + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + try: + os.makedirs(dst) + except Exception: + pass + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.isdir(srcname): + shutil.copytree(srcname, dstname, ignore=ignore) + else: + # Will raise a SpecialFileError for unsupported file types + shutil.copy2(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except shutil.Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + shutil.copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise shutil.Error(errors) + + +def _zip_file(target_dir): + root_dir = os.path.dirname(target_dir) + os.chdir(root_dir) + shutil.make_archive(os.path.basename(target_dir), format="gztar", + base_dir=os.path.basename(target_dir)) + + +def _strip_py(py_dir): + for base, dirs, files in os.walk(py_dir): + for name in files: + if name.endswith('.py'): + path = os.path.join(base, name) + logging.debug("Deleting %s", path) + os.unlink(path) + + +def main(): + # src_dir = sys.argv[1] + site_pacakge_dir = sys.argv[2] + target_dir = sys.argv[3] + + top_dir = sys.argv[4] + + shutil.rmtree(target_dir, ignore_errors=True) + os.makedirs(target_dir) + + for dir in ("bin", "etc"): + _copytree(os.path.join(top_dir, dir), + os.path.join(target_dir, dir)) + + shutil.copy2(os.path.join(top_dir, "README.md"), + os.path.join(target_dir, "README.md")) + + target_lib_dir = os.path.join(target_dir, "lib") + _copytree(site_pacakge_dir, target_lib_dir) + + _zip_file(target_dir) + + print("") + print("output dir %s" %(target_dir)) + +if __name__ == '__main__': + try: + main() + except Exception: + logging.exception("main except") + sys.exit(1) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a4d92cc --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +psutil diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..7177859 --- /dev/null +++ b/setup.py @@ -0,0 +1,32 @@ +from setuptools import setup, find_packages + + +install_requires=[] + +for line in open('requirements.txt'): + install_requires.append(line.strip()) + +setup(name='check_system_info', + version='0.0.1', + description='', + long_description="""\ +""", + # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers # nopep8 + classifiers=[ + "Programming Language :: Python", + ], + keywords='', + author='mh', + author_email='menghan@unary.com.cn', + url='', + license='GPL', + packages=find_packages(exclude=["ez_setup","test.*", "test"]), + namespace_packages=[], + include_package_data=True, + test_suite='nose.collector', + zip_safe=False, + install_requires=install_requires, + entry_points=""" + # -*- Entry points: -*- + """, + ) diff --git a/start_vscode.bat b/start_vscode.bat new file mode 100644 index 0000000..f41bc1c --- /dev/null +++ b/start_vscode.bat @@ -0,0 +1,6 @@ + +set PROJECT_HOME=%~dp0 + + +rem 确保vscode在path里面 +start code %PROJECT_HOME% diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2570642 --- /dev/null +++ b/tox.ini @@ -0,0 +1,46 @@ +[tox] +envlist = devenv +minversion = 1.6 +skipsdist = False + +[testenv] +install_command = pip install --force-reinstall -U {opts} {packages} +setenv = VIRTUAL_ENV={envdir} + NOSE_WITH_COVERAGE=1 + NOSE_COVER_BRANCHES=1 +deps = + -r{toxinidir}/requirements.txt + + +[testenv:devenv] +envdir = devenv +basepython = python3.8 +usedevelop = True + + + +[testenv:devenv2] +envdir = devenv2 +basepython = python2.7 +usedevelop = True + + +[testenv:py38-release] +basepython = python3.8 +deps = + -r{toxinidir}/requirements.txt + +commands = + {envpython} {toxinidir}/release.py {envdir} {envsitepackagesdir} {toxinidir}/build/check_system_info_v1.0.0 {toxinidir} + + + + +[testenv:py27-release] +basepython = python2.7 +deps = + -r{toxinidir}/requirements.txt + +commands = + {envpython} {toxinidir}/release.py {envdir} {envsitepackagesdir} {toxinidir}/build/check_system_info_v1.0.0 {toxinidir} +