本系列为我正在编写的Hull Cinema Club Web应用程序上的开发进度提供了时间表。 如果您还没有阅读我对项目的介绍,可以在这里找到。
在结束我以前的博客时,已经实现了电影导入程序的基本功能(即使某些代码会使您退缩)。 下一步是增加对多个电影院的支持,因为如果时间安排更好,我们经常会四处走动。 看到电影院是固定的,不需要更新,我决定只播种这些数据。 在Elixir中执行此操作的过程涉及使用Ecto库手动插入条目。 有一个简短的脚本可以使用Elixir构建工具运行。 没有复杂的库或编译后的代码,因此我发现它非常容易且无麻烦。
- 10电影院inspirar sua jornada como主持人
- 布鲁萨·德·布莱尔(Blair Witch,2016)
- Mukkabaaz是Kashyap对他的批评家的胜利打击,这部作品将定义2018年
- 现在,我将向您介绍韦斯·安德森的布达佩斯大酒店
- 杰德·罗琳(JK Rowling)
我需要遍历每个电影院才能检索它们的清单,作为.NET开发人员,我发现自己正在寻找“ foreach”的替代方案。 堆栈溢出告诉我Enum.each将是执行此操作的最简单方法。 每次将值传递给定义为第二个参数的函数时,它都会使用一个可枚举的对象并对其进行迭代。 以下代码从数据库中提取每个电影院并打印其名称…
电影院|> Repo.all |> Enum.each(fn(cinema)-> IO.inspection.name 结束)
然后,我将在接下来的五天中的每一天重复此过程,以使进口商不会仅提取今天的清单。 我怀疑可能有一种更“实用”的方式来执行此操作,并且我的脑子仍想用.NET术语进行思考,但它符合要求,并且比我以前使用的方法更简洁。
邮件通知
电影导入器的早期测试表明,按名称从OMDb查询电影详细信息并不总是按计划进行。 每当导入失败时,总是有必要通知我,最简单的通知自己的方法是通过电子邮件。 值得庆幸的是,有一个图书馆可以帮助我实现这一目标。
Bamboo是一个适应性强的库,用于通过多种不同方法(包括SMTP和Mailgun和Mandrill等外部服务)创建和发送电子邮件。 发送电子邮件就像定义电子邮件一样简单……
def missing_movie_details(movie)做 新邮件() |>到(“ rob.dmind@gmail.com”) |>来自(““ notifications@hullcinemaclub.com”) |> subject(“缺少#{movie.name}的电影信息”) |> text_body(“ ID为{{movie.id}的#{movie.name}的电影信息丢失。请尽快纠正。”) 结束
…并发送…
电影|> Email.missing_movie_details |> Mailer.deliver_later
HTML电子邮件的过程变得有些复杂,但是由于电子邮件只会被发送给我,因此我认为这对现阶段的需求来说是多余的。
Bamboo的另一个不错的功能是如何为开发和生产环境定义不同的适配器。 我的prod.exs文件使用SMTP适配器发送实时电子邮件,而在我的dev.exs中,我可以使用将电子邮件存储在内存中的本地适配器,以使收件箱不会被淹没。

一旦项目达到我向用户发送通知电子邮件的地步,最好将电子邮件分离到他们自己的单独应用程序中。 当然要考虑一些事情。
API问题
每当未找到特定电影的数据时,就会触发新实施的电子邮件通知。 通知泛滥成灾,他们很好地突出显示有多少电影导入失败。 此外,在仔细检查数据库后,很明显,许多电影导入都无声地失败了(例如,他们提取的信息只是错误的电影)。 这些失败中的绝大部分是由旧电影的现代翻拍造成的,例如It或Beauty and Beast。 如果不指定发行年份,则OMDb API将默认为电影的最早版本,而该版本很少是正确的。 不幸的是,假设这部电影是在今年发行的,偶尔也会有电影重新发行(这是最近在《电影世界》上角斗士的表演所证明的),这也是一场赌博。 我从偏移量知道,仅使用电影名称进行查询将是有问题的,但没有意识到它会严重影响导入的数据。 在最初导入的33部电影中,有6部是不正确的-占我数据的15%!
我的数据不准确,导致我寻找替代方法。 首先,我着眼于“查找任何电影”如何填充他们的数据并发现他们正在调用API。 返回的信息比CineList详细得多,并且关键地包含了电影发行的年份。 那时,我决定退出API,以提高数据质量。
“查找任何电影” API的结果证明有点复杂。 它正确地确定了电影的现代改编,但在某些情况下只是错误的。 最明显的例子是它声称的《杀手的保镖》,尽管它于2017年8月在全球范围内发布,但它还是在2016年发布了。总的来说,错误进口的数量有所改善,从6降至4。使用此API代替CineList; 通过使用OMDb的发行年份来查询它,它要么会给我正确的电影,要么会给我失败-不会因为同名电影而引起歧义。 这意味着,如果一部电影失败了,我会知道的,并且可能不会发布不正确的信息。
我遇到的问题证明了在我的应用程序中依赖第三方数据的问题。 不幸的是,由于收集了很多清单,所以没有实际的方法可以手动输入它们,因此,我能做的最好的就是尝试减轻损害。 在这种情况下,这意味着使错误导入的数据尽可能容易地进行更新。 无疑,将来会改进此过程,但是在编写本文时,我已经添加了使用电影的IMDb ID查询OMDb的函数。 这意味着我只需要指定ID,而不需要手动输入详细信息。
重构
有了所有这些最近的更改,我的代码库开始看起来有些混乱,可以整理一下。 在Elixir中寻找重构技巧时,我遇到了Credo,这是一种代码分析工具,可推荐最佳实践并促进一致的代码。

它能够突出显示我正在编写的代码中的许多问题,甚至能够为如何解决一些问题提供建议(总是很高兴有一个图书馆为我工作)。 大多数更改都是相当小的更改,涉及使用别名来排除模块名称并精简我的文件,但是应突出显示一些突出的代码区域。 最明显的一个证实了我的怀疑,尽管我暂时无法想出一个更好的选择,但我不应该嵌套每个循环。
我肯定会定期使用Credo,以确保我不会犯草率的错误。
部署
是时候将电影导入器部署到实时服务器上,看看它在野外的表现如何。 Edeliver允许您构建和部署Elixir应用程序,同时提供有用的命令,使您可以远程停止和启动它们。 实际上,实际上我发现启动和运行它有点棘手,部分原因是它依赖于git。 任何未提交给我的存储库的内容都将被忽略,包括包含我的实时数据库和API密钥凭据的秘密文件。 在文档中有解决此问题的方法,但是在标准构建过程中忽略这样的通用要求似乎很奇怪。
我发现的另一个烦恼是使用混合构建工具并在实时服务器上运行数据库迁移。 可能很幼稚,但是我无法找到一种方法来运行它们,而无需更改本地计算机上的开发配置以指向生产数据库并在本地执行命令。 这不一定是一个大问题,但是我无法在服务器本身上执行所有需要的操作似乎很可耻。
总而言之,我发现部署过程有点麻烦。 实际花费了4到5次提交才能使应用程序顺利构建并开始运行。 话虽这么说,一旦初始版本启动并运行,随后的大多数发行版都非常容易。
接下来是什么?
导入器现在已经在生产环境中运行了3天,并且每天导入列表,同时在无法获取电影信息时发送电子邮件。 尽管电影数据导入的成功率比我想要的要低,但我意识到这是一个不可避免的问题,同时严重依赖其他人提供的服务。
该项目的第一个主要障碍已经克服,我可以将注意力转向实际构建Hull Cinema Club网络应用程序。 最初的计划是为HCC构建API,并为大多数功能使用前端Javascript框架,但是我可能会重新考虑这一点,并使用Phoenix的服务器渲染模板。 我必须写的Javascript越少越好!
如果您想看一下电影导入程序背后的代码,可以在这里找到我的存储库。 任何建议或反馈都非常欢迎。