Ruby 转发带有附件的电子邮件
我希望在不下载附件然后重新/附加到新电子邮件的情况下执行此操作。Ruby 转发带有附件的电子邮件,ruby,mail-gem,Ruby,Mail Gem,我希望在不下载附件然后重新/附加到新电子邮件的情况下执行此操作。 这就是我尝试过的: $emailslist.each do |e| Mail.deliver do from fromstr to "mailman@somedomain.com" subject "[Events] #{subjectstr}" if e.attachments.length>0 e.attachments.each do |a| add
这就是我尝试过的:
$emailslist.each do |e|
Mail.deliver do
from fromstr
to "mailman@somedomain.com"
subject "[Events] #{subjectstr}"
if e.attachments.length>0
e.attachments.each do |a|
add_file a
end
end
end
end
#error in 'e.attachments.each'=>undefined method `attachments' for
#<TypeError: can't convert nil into String>
这是未经测试的,并不是真正试图找到或修复错误。这是为了展示你的代码应该是什么样子,用更地道的Ruby代码编写。因此,它可能会解决您看到的问题。如果没有,至少您会更好地了解应该如何编写代码:
require 'mail'
- 为重用的文本字符串定义一些常量。在顶部执行此操作,这样您就不必在多个位置搜索代码来更改内容,从而可能会错过其中一个
PATH_TO_FILES = "C:/Users/j.de_miguel/Desktop/mailman.forma" BODY_BOILERPLATE_FORMAT = "%s\nmailman@forma.culturadigital.cc para darte de baja escribe \"baja\" a info@culturadigital.cc"
- 将方法分组到文件顶部的常量之后
- 我们使用
打开,而不是'a'
。我们不需要读/写,我们只需要写'a+'
- 这将根据需要打开和关闭文件
- 自动关闭文件会进行刷新李>
- 如果您经常调用log方法,那么有更好的方法可以做到这一点,但这不是一个重量级脚本
- 我正在使用
根据路径构建文件名File.join
知道路径分隔符并自动执行正确的操作李>File.join
可以轻松创建标准输出格式String.%%
def log(text) File.open(File.join(PATH_TO_FILES, "error_log2.txt"), 'a') do |log_file| log_file.puts "%s : %s" % [Time.now, text] end end
- Ruby中的方法名是snake_大小写,而不是CamelCase
- 没有理由拥有多个
gsub代码>也不需要条件测试。如果要清除的子字符串存在于字符串
中,则将执行此操作,否则将继续。链接gsub
方法将代码减少到一行李>gsub
可能/应该是gsub
,除非您知道字符串中可能有多个点击需要替换sub
是冗余的,所以我们不使用它,除非我们显式地返回一个值以过早地离开一个块return
def delete_subject_recursion(subjstr) subjstr.gsub(/.\[FORMA 2013\]/,"").gsub(/((?i)Re: ){2,}/, "Re: ") end
- 由于
应为布尔值,因此使用来执行测试。如果找到任何匹配项,则退出并返回registed
true
def user_is_registered(mailaddr) registered = subscribers.any?{ |s| mailaddr == s } log("user #{ mailaddr } attempted to mailman") unless registered registered end
- 使用
迭代文件的行foreach
subscribers = [] File.foreach(File.join(PATH_TO_FILES, "subscribers2.txt")) do |line| subscribers << line.chomp if line['@'] end puts subscribers log('') Mail.defaults do retriever_method( :imap, { :address => "imap.1and1.es", :port => 143, :user_name => "mailman@somedomain.com", :password => "xxxxxxxx", :enable_ssl => false } ) delivery_method( :smtp, { :address => "smtp.1and1.es", :port => 587, :domain => '1and1.es', :user_name => 'mailman@somaedomain.com', :password => 'xxxxxxxxxxxx', :authentication => 'plain', :enable_starttls_auto => true } ) end #emailslist=Mail.find(keys: ['NOT','SEEN']) emailslist = [Mail.last] emailslist.each do |e|
可以使用后续条件
if
测试将其重构为简单的单行:
e.attachments.each { |a| add_file a.encoded } if e.attachments.length > 0
当你做一些简单的事情时,用这样一行就可以了。不要将它们用于更复杂的代码,因为这样会产生视觉噪音,这会使代码难以理解和阅读
但是让我们看看上面的代码实际上在做什么e.attachments
在此上下文中似乎返回一个数组或某种可枚举集合,否则每个
都不起作用length
将告诉我们附件返回的“数组”(或任何数组)中存在多少元素
如果length
为零,那么我们不想做任何事情,因此我们可以说:
e.attachments.each { |a| add_file a.encoded } unless e.attachments.empty?
(假设附件
实现了空?
方法。)
不过这也有点多余。如果e.attachments
已为空,则每个将做什么?它将检查附件
是否返回了一个包含任何元素的数组,如果数组为空,它将完全跳过其块,就像触发了
条件时的后续一样有效。所以,我们可以用这个来代替:
e.attachments.each { |a| add_file a.encoded }
Ruby样式指南:
第二个是基于第一个。铁皮人的答案大多有效。我更改了添加附件的方式,因为他的版本不适合我
e.attachments.each { |a| attachments[a.filename] = a.decoded } if e.attachments.length > 0
它不起作用的原因是e
没有值,它是nil
。那么为什么e
没有值呢?您的$emailslist
是否为空?或者,它是否包含nil
值?您没有向我们展示足够的信息来合理地回答您的问题。e
不是零,否则它将无法通过if语句。如果我打印e.attachments.inspect
它实际上会显示附件。如果使用ruby-cwW2 path/to/your/application运行代码会发生什么情况?你正在滥用$global
变量。哇,谢谢你的ruby课程!真的,非常感谢-我从来没有机会知道这种东西,否则,因为我总是独自编码+没有计算机科学背景:)/我会测试你的代码,看看它是如何运行的。没问题。每种语言都有其风格指南。我为Ruby添加了两个链接,一个基于另一个。把它们通读几遍总是好的,然后在学习的过程中定期重读。指南只是“指南”,而不是法律。使用基于可读性和可维护性的最有意义的内容,因为这有助于我们理解一年后编写的内容。我还为“添加附件”代码添加了一些重构。仍然不能保证代码能正常工作,因为我没有设置系统来测试它,但它还是更为惯用的Ruby。
e.attachments.each { |a| add_file a.encoded } unless e.attachments.empty?
e.attachments.each { |a| add_file a.encoded }
e.attachments.each { |a| attachments[a.filename] = a.decoded } if e.attachments.length > 0