我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于Python怎么编写微信清理工具

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于Python怎么编写微信清理工具

这篇“基于Python怎么编写微信清理工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写微信清理工具”文章吧。

主要功能

它可以自动删除 PC 端微信自动下载的大量文件、视频、图片等数据内容,释放几十 G 的空间占用,而且不会删除文字的聊天记录,可以放心使用。

工作以后,微信的群聊实在太多了,动不动就被拉入一个群中,然后群聊里大部分都是与自己无关的各大群聊中的文件、视频、图片等内容,会非常占用存储空间。

  • 自动识别微信账号,支持用户选择自定义路径;

  • 同时管理多个账号,保留配置参数,打开即用;

  • 自由设置想要删除的文件类型,包括图片类缓存、文件、图片、视频;

  • 自由设置需要删除的文件的距离时间,默认 365 天;

  • 删除后的文件放置在回收站中,检查后自行清空,防止删错文件;

  • 支持删除进度的显示;

工具的主界面如下

基于Python怎么编写微信清理工具

运行环境

Windows,后续可能会支持 Mac。

核心代码

import sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsDropShadowEffect, QListWidgetItem, QListView, QWidget, \    QLabel, QHBoxLayout, QFileDialogfrom PyQt5.QtCore import Qt, QPropertyAnimation, QEasingCurve, QThread, pyqtSignal, QMutex, QSize, QEvent, QPointfrom PyQt5.QtGui import QMouseEvent, QCursor, QColorfrom PyQt5.uic import loadUifrom pathlib import Path, PureWindowsPathfrom dateutil import relativedeltaimport utils.resourcesimport os, datetime, time, re, math, shutil, jsonfrom utils.deleteThread import *from utils.multiDeleteThread import multiDeleteThreadfrom utils.selectVersion import *from utils.selectVersion import check_dir, existing_user_configworking_dir = os.path.split(os.path.realpath(__file__))[0]# 主窗口class Window(QMainWindow):    def mousePressEvent(self, event):        # 重写一堆方法使其支持拖动        if event.button() == Qt.LeftButton:            self.m_drag = True            self.m_DragPosition = event.globalPos() - self.pos()            event.accept()            # self.setCursor(QCursor(Qt.OpenHandCursor))    def mouseMoveEvent(self, QMouseEvent):        try:            if Qt.LeftButton and self.m_drag:                self.move(QMouseEvent.globalPos() - self.m_DragPosition)                QMouseEvent.accept()        except:            pass    def mouseReleaseEvent(self, QMouseEvent):        self.m_drag = False        # self.setCursor(QCursor(Qt.ArrowCursor))    def _frame(self):        # 边框        self.setWindowFlags(Qt.FramelessWindowHint)        self.setAttribute(Qt.WA_TranslucentBackground, True)        # 阴影        effect = QGraphicsDropShadowEffect(blurRadius=12, xOffset=0, yOffset=0)        effect.setColor(QColor(25, 25, 25, 170))        self.mainFrame.setGraphicsEffect(effect)    def doFadeIn(self):        # 动画        self.animation = QPropertyAnimation(self, b'windowOpacity')        # 持续时间250ms        self.animation.setDuration(250)        try:            # 尝试先取消动画完成后关闭窗口的信号            self.animation.finished.disconnect(self.close)        except:            pass        self.animation.stop()        # 透明度范围从0逐渐增加到1        self.animation.setEasingCurve(QEasingCurve.InOutCubic)        self.animation.setStartValue(0)        self.animation.setEndValue(1)        self.animation.start()    def doFadeOut(self):        self.animation.stop()        # 动画完成则关闭窗口        self.animation.finished.connect(self.close)        # 透明度范围从1逐渐减少到0s        self.animation.setEasingCurve(QEasingCurve.InOutCubic)        self.animation.setStartValue(1)        self.animation.setEndValue(0)        self.animation.start()    def setWarninginfo(self, text):        self.lab_info.setStyleSheet("""            .QLabel {                border:1px solid #ffccc7;                border-radius:3px;                line-height: 140px;                padding: 5px;                color: #434343;                background: #fff2f0;            }            """)        self.lab_info.setText(text)    def setSuccessinfo(self, text):        self.lab_info.setStyleSheet("""            .QLabel {                border:1px solid #b7eb8f;                border-radius:3px;                line-height: 140px;                padding: 5px;                color: #434343;                background: #f6ffed;            }            """)        self.lab_info.setText(text)class ConfigWindow(Window):    Signal_OneParameter = pyqtSignal(int)    config = {}    def _connect(self):        self.combo_user.currentIndexChanged.connect(self.refresh_ui)        self.btn_close.clicked.connect(self.save_config)        self.btn_file.clicked.connect(self.open_file)    def open_file(self):        openfile_path = QFileDialog.getExistingDirectory(self, '选择微信数据目录', '')        if not openfile_path or openfile_path == '':            return False        if check_dir(openfile_path) == 0:            self.setSuccessinfo('读取路径成功!')            list_ = os.listdir(openfile_path)            user_list = [                elem for elem in list_                if elem != 'All Users' and elem != 'Applet'            ]            # 如果已有用户配置,那么写入新的用户配置,否则默认写入新配置            dir_list = []            user_config = []            existing_user_config_dic = existing_user_config()            for user_wx_id in user_list:                dir_list.append(os.path.join(openfile_path, user_wx_id))                if user_wx_id in existing_user_config_dic:                    user_config.append(existing_user_config_dic[user_wx_id])                else:                    user_config.append({                        "wechat_id": user_wx_id,                        "clean_days": "365",                        "is_clean": False,                        "clean_pic_cache": True,                        "clean_file": False,                        "clean_pic": True,                        "clean_video": True,                        "is_timer": True,                        "timer": "0h"                    })            config = {"data_dir": dir_list, "users": user_config}            with open(                    working_dir + "/config.json", "w", encoding="utf-8") as f:                json.dump(config, f)            self.load_config()        else:            self.setWarninginfo('请选择正确的文件夹!一般是WeChat Files文件夹。')    def save_config(self):        self.update_config()        self.doFadeOut()    def check_wechat_exists(self):        self.selectVersion = selectVersion()        self.version_scan = self.selectVersion.getAllPath()[0]        self.users_scan = self.selectVersion.getAllPath()[1]        if len(self.version_scan) == 0:            return False        else:            return True    def load_config(self):        fd = open(working_dir + "/config.json", encoding="utf-8")        self.config = json.load(fd)        self.combo_user.clear()        for value in self.config["users"]:            self.combo_user.addItem(value["wechat_id"])        self.line_gobackdays.setText(            str(self.config["users"][0]["clean_days"]))        self.check_is_clean.setChecked(self.config["users"][0]["is_clean"])        self.check_picdown.setChecked(self.config["users"][0]["clean_pic"])        self.check_files.setChecked(self.config["users"][0]["clean_file"])        self.check_video.setChecked(self.config["users"][0]["clean_video"])        self.check_picscache.setChecked(            self.config["users"][0]["clean_pic_cache"])        self.setSuccessinfo("加载配置文件成功")    def refresh_ui(self):        self.config = open(working_dir + "/config.json", encoding="utf-8")        self.config = json.load(self.config)        for value in self.config["users"]:            if value["wechat_id"] == self.combo_user.currentText():                self.line_gobackdays.setText(str(value["clean_days"]))                self.check_is_clean.setChecked(value["is_clean"])                self.check_picdown.setChecked(value["clean_pic"])                self.check_files.setChecked(value["clean_file"])                self.check_video.setChecked(value["clean_video"])                self.check_picscache.setChecked(value["clean_pic_cache"])    def create_config(self):        true = True        if not os.path.exists(working_dir + "/config.json"):            if not self.check_wechat_exists():                self.setWarninginfo("默认位置没有微信,请自定义位置")                return            self.config = {"data_dir": self.version_scan, "users": []}            for value in self.users_scan:                self.config["users"].append({                    "wechat_id": value,                    "clean_days": 365,                    "is_clean": False,                    "clean_pic_cache": true,                    "clean_file": False,                    "clean_pic": true,                    "clean_video": true,                    "is_timer": true,                    "timer": "0h"                })            with open(                    working_dir + "/config.json", "w", encoding="utf-8") as f:                json.dump(self.config, f)            self.load_config()            self.setSuccessinfo("加载配置文件成功")        else:            self.setSuccessinfo("加载配置文件成功")            self.load_config()    def update_config(self):        if not len(self.config):            return        else:            for value in self.config["users"]:                if value["wechat_id"] == self.combo_user.currentText():                    try:                        days = int(self.line_gobackdays.text())                        if days < 0:                            value["clean_days"] = "0"                        else:                            value["clean_days"] = self.line_gobackdays.text()                    except ValueError:                        value["clean_days"] = "0"                    value["is_clean"] = self.check_is_clean.isChecked()                    value["clean_pic"] = self.check_picdown.isChecked()                    value["clean_file"] = self.check_files.isChecked()                    value["clean_video"] = self.check_video.isChecked()                    value["clean_pic_cache"] = self.check_picscache.isChecked()            with open(working_dir + "/config.json", "w", encoding="utf-8") as f:                json.dump(self.config, f)            self.setSuccessinfo("更新配置文件成功")            self.Signal_OneParameter.emit(1)    def __init__(self):        super().__init__()        loadUi(working_dir + "/images/config.ui", self)        self._frame()        self._connect()        self.doFadeIn()        self.create_config()        self.show()class MainWindow(Window):    def deal_emit_slot(self, set_status):        if set_status and not self.config_exists:            self.setSuccessinfo("已经准备好,可以开始了!")            self.config_exists = True    def closeEvent(self, event):        sys.exit(0)    def eventFilter(self, object, event):        if event.type() == QEvent.MouseButtonPress:            if object == self.lab_close:                self.doFadeOut()                return True            elif object == self.lab_clean:                try:                    self.setSuccessinfo("正在清理中...")                    self.justdoit()                except:                    self.setWarninginfo("清理失败,请检查配置文件后重试")                return True            elif object == self.lab_config:                cw = ConfigWindow()                cw.Signal_OneParameter.connect(self.deal_emit_slot)                return True        return False    def _eventfilter(self):        # 事件过滤        self.lab_close.installEventFilter(self)        self.lab_clean.installEventFilter(self)        self.lab_config.installEventFilter(self)    def get_fileNum(self, path, day, picCacheCheck, fileCheck, picCheck,                    videoCheck, file_list, dir_list):        dir_name = PureWindowsPath(path)        # Convert path to the right format for the current operating system        correct_path = Path(dir_name)        now = datetime.datetime.now()        if picCacheCheck:            path_one = correct_path / 'Attachment'            path_two = correct_path / 'FileStorage/Cache'            self.getPathFileNum(now, day, path_one, path_two, file_list,                                dir_list)        if fileCheck:            path_one = correct_path / 'Files'            path_two = correct_path / 'FileStorage/File'            self.getPathFileNum(now, day, path_one, path_two, file_list,                                dir_list)        if picCheck:            path_one = correct_path / 'Image/Image'            path_two = correct_path / 'FileStorage/Image'            self.getPathFileNum(now, day, path_one, path_two, file_list,                                dir_list)        if videoCheck:            path_one = correct_path / 'Video'            path_two = correct_path / 'FileStorage/Video'            self.getPathFileNum(now, day, path_one, path_two, file_list,                                dir_list)    def pathFileDeal(self, now, day, path, file_list, dir_list):        if os.path.exists(path):            filelist = [                f for f in os.listdir(path)                if os.path.isfile(os.path.join(path, f))            ]            for i in range(0, len(filelist)):                file_path = os.path.join(path, filelist[i])                if os.path.isdir(file_path):                    continue                timestamp = datetime.datetime.fromtimestamp(                    os.path.getmtime(file_path))                diff = (now - timestamp).days                if diff >= day:                    file_list.append(file_path)    def getPathFileNum(self, now, day, path_one, path_two, file_list,                       dir_list):        # caculate path_one        self.pathFileDeal(now, day, path_one, file_list, dir_list)        td = datetime.datetime.now() - datetime.timedelta(days=day)        td_year = td.year        td_month = td.month        # caculate path_two        if os.path.exists(path_two):            osdir = os.listdir(path_two)            dirlist = []            for i in range(0, len(osdir)):                file_path = os.path.join(path_two, osdir[i])                if os.path.isdir(file_path):                    dirlist.append(osdir[i])            for i in range(0, len(dirlist)):                file_path = os.path.join(path_two, dirlist[i])                if os.path.isfile(file_path):                    continue                if re.match('\d{4}(\-)\d{2}', dirlist[i]) != None:                    cyear = int(dirlist[i].split('-', 1)[0])                    cmonth = int(dirlist[i].split('-', 1)[1])                    if self.__before_deadline(cyear, cmonth, td_year,                                              td_month):                        dir_list.append(file_path)                    else:                        if cmonth == td_month:                            self.pathFileDeal(now, day, file_path, file_list,                                              dir_list)    def __before_deadline(self, cyear, cmonth, td_year, td_month):        if cyear < td_year:            return True        elif cyear > td_year:            return False        elif cyear == td_year:            return cmonth < td_month    def callback(self, v):        value = v / int((self.total_file + self.total_dir)) * 100        self.bar_progress.setValue(value)        if value == 100:            out = "本次共清理文件" + str(self.total_file) + "个,文件夹" + str(                self.total_dir) + "个。请前往回收站检查并清空。"            self.setSuccessinfo(out)            return    def justdoit(self):  # 这个Api设计的太脑残了,其实dir可以直接放在user里的... 有时间改吧        fd = open(working_dir + "/config.json", encoding="utf-8")        self.config = json.load(fd)        i = 0        need_clean = False        thread_list = []        total_file = 0        total_dir = 0        share_thread_arr = [0]        for value in self.config["users"]:            file_list = []            dir_list = []            if value["is_clean"]:                self.get_fileNum(self.config["data_dir"][i],                                 int(value["clean_days"]),                                 value["clean_pic_cache"], value["clean_file"],                                 value["clean_pic"], value["clean_video"],                                 file_list, dir_list)            if len(file_list) + len(dir_list) != 0:                need_clean = True                total_file += len(file_list)                total_dir += len(dir_list)                thread_list.append(                    multiDeleteThread(file_list, dir_list, share_thread_arr))                thread_list[-1].delete_process_signal.connect(self.callback)            i = i + 1        if not need_clean:            self.setWarninginfo("没有需要清理的文件")        else:            self.total_file = total_file            self.total_dir = total_dir            for thread in thread_list:                thread.run()    def __init__(self):        super().__init__()        loadUi(working_dir + "/images/main.ui", self)        self._frame()        self._eventfilter()        self.doFadeIn()        self.config_exists = True        # 判断配置文件是否存在        if not os.path.exists(working_dir + "/config.json"):            self.setWarninginfo("配置文件不存在!请单击“设置”创建配置文件")            self.config_exists = False        self.show()if __name__ == '__main__':    app = QApplication([])    win = MainWindow()    app.exec_()

以上就是关于“基于Python怎么编写微信清理工具”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于Python怎么编写微信清理工具

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于Python怎么编写微信清理工具

这篇“基于Python怎么编写微信清理工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写微信清理工具
2023-06-30

基于Python编写一个ISBN查询工具

这篇文章主要为大家详细介绍了如何利用Python编写一个简单的ISBN查询工具,可以用于图书管理、图书销售、图书收集和阅读等场景,需要的可以参考一下
2023-05-19

基于WPF怎么编写一个串口转UDP工具

这篇“基于WPF怎么编写一个串口转UDP工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于WPF怎么编写一个串口转UDP
2023-07-05

基于Python怎么编写一个微博抽奖小程序

本篇内容主要讲解“基于Python怎么编写一个微博抽奖小程序”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“基于Python怎么编写一个微博抽奖小程序”吧!开发工具Python版本:3.7.8相关
2023-06-30

Python怎么编写PDF拆分工具

这篇文章主要介绍“Python怎么编写PDF拆分工具”,在日常操作中,相信很多人在Python怎么编写PDF拆分工具问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么编写PDF拆分工具”的疑惑有所
2023-06-29

怎么选择基于ITIL的管理工具

这篇文章的内容主要围绕怎么选择基于ITIL的管理工具进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获! ITIL作为ITSM系统的国际标准,
2023-06-05

基于Python怎么编写一个点名器

这篇文章主要介绍“基于Python怎么编写一个点名器”,在日常操作中,相信很多人在基于Python怎么编写一个点名器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于Python怎么编写一个点名器”的疑惑有所
2023-07-02

基于Python怎么实现对比Exce的工具

这篇“基于Python怎么实现对比Exce的工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么实现对比E
2023-06-29

怎么用python编写一个图片拼接工具

本文小编为大家详细介绍“怎么用python编写一个图片拼接工具”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用python编写一个图片拼接工具”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。代码展示这里写了两
2023-06-28

基于Python怎么编写一个语音合成系统

这篇文章主要介绍了基于Python怎么编写一个语音合成系统的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Python怎么编写一个语音合成系统文章都会有所收获,下面我们一起来看看吧。背景一直对语音合成系统比较
2023-06-29

基于Python怎么编写一个刷题练习系统

这篇“基于Python怎么编写一个刷题练习系统”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写一个刷题
2023-07-05

基于Python怎么编写一个二维码生成器

这篇“基于Python怎么编写一个二维码生成器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写一个二维
2023-07-02

如何分析使用wxpy这个基于python实现的微信工具库的常见问题

本篇文章为大家展示了如何分析使用wxpy这个基于python实现的微信工具库的常见问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。使用如下的命令行安装:pip install wxpyCollec
2023-06-04

使用python怎么编写一个本地应用搜索工具

这篇文章主要介绍了使用python怎么编写一个本地应用搜索工具,此处通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考价值,需要的朋友可以参考下:python可以做什么Python是一种编程语言,内置了许多有效的工具,Pyt
2023-06-06

基于Python怎么编写一个监控CPU的应用系统

这篇“基于Python怎么编写一个监控CPU的应用系统”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写
2023-07-02

怎么用Python实现基于Pyqt5的简单电影搜索工具

这篇文章主要介绍“怎么用Python实现基于Pyqt5的简单电影搜索工具”,在日常操作中,相信很多人在怎么用Python实现基于Pyqt5的简单电影搜索工具问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用
2023-06-02

Python数据处理pandas读写操作IO工具CSV怎么使用

这篇“Python数据处理pandas读写操作IO工具CSV怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Pytho
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录