百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

用Python为我儿子的童年记忆创建电子邮件服务

toyiye 2024-06-27 00:50 24 浏览 0 评论



许多年来--自从我现在还在蹒跚学步的儿子还是个小婴儿以来--我一直在记录各种童年的成就或记忆。当我第一次想到这个的时候,我睡眠不足,无法决定储存这些信息的最佳方法,所以我选择了一个非常简单的方法。我刚刚创建了一个Word文档,其中包含两个列:日期和活动/成就/内存。例如:

这是非常灵活的,因为它允许我在这份文件中保留我想要的任何东西--而且它是可携带的(对于任何能够阅读Word文档的人来说)--并且可以为非技术人员(比如我儿子的祖父母)使用。

入门Python其实很容易,但是我们要去坚持学习,每一天坚持很困难,我相信很多人学了一个星期就放弃了,为什么呢?其实没有好的学习资料给你去学习,你们是很难坚持的,这是小编收集的Python入门学习资料关注,转发,私信小编“01”,即可免费领取!希望对你们有帮助


但是过了一段时间,我想知道我是否做出了正确的决定:难道我不应该把它放到其他可以编程访问的格式中吗?毕竟,如果我在他的整个童年都这么做的话,那么我会在…里面有很多有趣的数据。

好吧,事实证明一个字表不是也是存储这类数据的格式很糟糕,您可以通过Python轻松地访问它。

一旦我意识到这一点,我就想出了自己想要创造的东西:每天早上给我发电子邮件,列出我写的日记条目。那一天在前几年。我做了这么多的模特时间跳与照片、推特等类似的应用程序,所以我称之为julian_timehop .

如果您只想查看代码,那么请查看GitHub回购-否则,继续读下去,看看我是怎么做到的.

步骤

让我们首先考虑一下我们需要采取的主要步骤是:

  1. 首先我们需要拿到文件。我定期更新它,它在我的笔记本上运行-而这个脚本需要在我的Linux服务器上运行,所以它可以轻松地每天同时运行。最简单的方法是将文档存储在Dropbox中,并在运行脚本时使用DropboxAPI获取副本。
  2. 然后,我们需要解析文档来提取日记条目表。
  3. 一旦我们得到了表,我们就可以将其子集为与今天的日期相匹配的行(忽略年份)
  4. 然后,我们需要根据这些行准备电子邮件的文本,然后发送电子邮件。

现在让我们依次来看看每一个。

从Dropbox获取文件

我们希望使用DropboxAPI进行尽可能简单的操作:登录并检索文件的最新版本。我以前使用过Python中的DropboxAPI(关于分析我用Dropbox编写论文的时间表,请参阅MyPost),它非常容易。实际上,只需四行代码就可以完成此任务。

首先,我们需要连接到Dropbox并进行身份验证。为此,我们将使用DropboxAPI密钥(参见这里有关如何获得一个)的说明)。我们不希望将这个API密钥直接包含在代码中--因为我们可能会意外地与其他人共享它(例如,通过将代码上传到Gizub)--所以我们存储在一个名为DROPBOX_KEY .

我们可以通过以下方法从这个环境变量中获得密钥

dropbox_key = os.environ.get('DROPBOX_KEY')

然后,我们可以创建一个Dropboxapi连接并进行身份验证。

dbx = dropbox.Dropbox(dropbox_key)

要下载文件,我们只需调用files_download_to_file方法

dbx.files_download_to_file(output_filename, path)

在这种情况下,path参数是Dropbox文件夹中文件的路径--在我的示例中,路径是/Notes and diary entries for Julian.docx因为该文件位于根Dropbox文件夹中。

把这些放在一起,我们就可以从Dropbox下载一个文件了。

def download_file(path):
 """
 Download a file from Dropbox, returning the local filename of the downloaded file

 Requires the DROPBOX_KEY env var to be set to a valid Dropbox API key
 """
 dropbox_key = os.environ.get('DROPBOX_KEY')
 dbx = dropbox.Dropbox(dropbox_key)
 output_filename = 'document.docx'
 dbx.files_download_to_file(output_filename, path)

 return output_filename

这是完成的第一步;接下来,我们需要从Word文档中提取表。

提取表

在之前的工作中,我做了一些工作,包括自动创建Powerpoint演示文稿,并且我使用了优秀的Pythonpptx用于读取和写入Powerpoint文件的库。方便地,有一个可供Word文档使用的姐妹库,名为Python-docx以类似的方式工作。

我们将把Word表转换为熊猫DataFrame,所以在安装之后python-docx我们需要进口Document班级,还有熊猫本身

from docx import Document
import pandas as pd

我们可以通过创建Document以文件名作为参数初始化

doc = Document(filename)

这个doc对象具有各种有用的方法和属性--其中之一是文档中的表列表。我们知道我们想解析第一个表,所以我们只需选择第0次索引。

tab = doc.tables[0]

要创建熊猫DataFrame,我们需要一个包含每一列内容的列表:这里意味着日期列表和条目列表。

tab.column_cells(0)在列0中的所有单元格上给出一个迭代器,并且每个单元格都有一个.text方法来给出该单元格的文本内容,因此我们可以编写一个列表理解,将所有内容提取到列表中。

dates = [cell.text for cell in tab.column_cells(0)]

然后我们可以使用非常方便的 pd.to_datetime 函数将这些对象转换为实际日期对象。我们通过辩论errors='coerce'强制它解析列表中的所有条目,如果其中一个条目不是有效日期,则不给出错误(在本例中,它将返回NaT或不是时候 ).

我们可以对描述进行同样的操作,然后将描述和日期放在一个DataFrame中。

以下是完整的代码:

def read_table_from_doc(filename):
 doc = Document(filename)
 tab = doc.tables[0]

 dates = [cell.text for cell in tab.column_cells(0)]
 dates = pd.to_datetime(dates, errors='coerce')

 descs = [cell.text for cell in tab.column_cells(1)]

 df = pd.DataFrame({'desc':descs}, index=dates)

 return df

为电子邮件创建文本

下一步是创建文本,输入电子邮件,列出日期和各种记忆。我想要这样的输出:

12月1日

2018:

2018年记忆

2018:

2018年的另一个记忆

2017:

2017年的记忆

这方面的代码相当简单,我只会提到有趣的部分。

首先,我们创建了DataFrame的一个子集,其中只有日期与今天的日期相同的行(忽略年份):

today = datetime.datetime.now()
subdf = df[(df.index.month == today.month) & (df.index.day == today.day)]

这里我们将两个布尔索引操作与&-不过,请记住使用括号,因为这些布尔表达式中的优先级顺序并不总是以您预期的方式工作(我多次被这种情况所困扰)。

因为我知道这只会在我的服务器上运行,所以我可以使用新的Python3.7特性,所以我使用了F-字符串...这意味着创建电子邮件正文的循环主体如下所示

text += f"<p><b>{i.year!s}:</b></br>{row['desc']}</p>\n\n"

在这里,我们包括了一些变量,比如i.year(日期时间索引的年份值)和row['desc'](的值)desc(这一行的列)。

将其组合到一个函数中会得到以下代码,这些代码要么返回电子邮件的HTML文本,要么返回电子邮件的HTML文本。None如果没有与此日期匹配的事件

def get_formatted_message(df):
 today = datetime.datetime.now()

 subdf = df[(df.index.month == today.month) & (df.index.day == today.day)]

 if len(subdf) == 0:
 return

 title_date = datetime.datetime.now().strftime('%d %B')
 text = f'<h2>{title_date}</h2>\n\n'
 for i, row in subdf.iterrows():
 text += f"<p><b>{i.year!s}:</b></br>{row['desc']}</p>\n\n"

 return text

发送电子邮件

我以前写过用Python发送电子邮件的代码,并且遇到了很大的困难。电子邮件比很多人想象的要难得多,而且我的电子邮件常常从来没有发过,也没有到达目的地,也没有以其他方式破译过。

这一次,我通过使用电子邮件图书馆。写一个send_email使用这个库的函数非常容易:

def send_email(text):
 message = emails.html(html=text,
 subject='Julian Timehop',
 mail_from=('Julian Timehop Emailer', '<a href="/cdn-cgi/l/email-protection" data-cfemail="d7a5b8b5beb997a5a3a0bebba4b8b9f9b4b8ba">[email protected]</a>'))

 password = os.environ.get('SMTP_PASSWORD')

 r = message.send(to=('R Wilson', '<a href="/cdn-cgi/l/email-protection" data-cfemail="e69489848f88a69492918f8a958988c885898b">[email protected]</a>'),
 smtp={'host':'mail.rtwilson.com',
 'port': 465, 'ssl': True,
 'user': '<a href="/cdn-cgi/l/email-protection" data-cfemail="64160b060d0a241610130d08170b0a4a070b09">[email protected]</a>', 'password': password})

上面的所有代码都是不言自明的:我们正在创建一个HTML电子邮件消息(它包含所有必要的转义和编码细节),从另一个环境变量获取密码,然后发送电子邮件。放轻松!

把一切都放在一起

我们现在已经为每个步骤编写了一个函数,现在我们只需要将这些函数放在一起。用这种方式编写脚本的好处是,脚本的主要部分只有几行。

在这种情况下,我们所需要的就是

filename = download_file('/Notes and diary entries for Julian.docx')
df = read_table_from_doc(filename)
text = get_formatted_message(df)
if text is not None:
 send_email(text)

它的另一个好处是,对于将来返回它的任何人(包括您自己)来说,在深入研究细节之前,很容易获得脚本所做的概述。

所以,我现在把这个设置在我的服务器上,每天早上给我发一封电子邮件,上面有一些关于我儿子童年的记忆。以下是更多快乐的回忆,请记住电码如果你感兴趣的话。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码