У меня есть пачка скриптов на ruby, которые по cron-у отчёты разные в csv делают и на почту высылают.
Правда там для mysql используется старый модуль, да и в ruby я не мастер.
Как-то так:
Код:
require 'rubygems'
require 'date'
require 'iconv'
require 'active_record/vendor/mysql'
require 'zip/zip'
require 'rmail'
require 'net/smtp'
#
#Скрипт создает отчет по изменениям лимитов за предыдущий день
#в формате csv и посылает его на почту, а также сохраняет локально и запаковывает в архив
#
class Main
def self.mainloop
report_path="reports/"
mail_title= "Ежедневный отчет по установке лимитов за #{Date.today-1}"
mail_to="test1@provider.ru test2@provider.ru"
mail_from="test@provider.ru"
host = '127.0.0.1'
login = 'bgbilling'
dbname = 'bgbilling'
password = 'bgbilling'
@db = Mysql.connect(host, login, password, dbname)
@db.query("set names utf8")
unless @db
puts "Can't connect to database"
exit 1
end
report="Договор;Название;Предыдущая установка лимита;Установленный лимит;На сколько дней;Дата;Пользователь;Комментарий;\n"
list=@db.query("select
c.title,
supertitle(c.id) name,
(select nvalue from log_contract_limit ll where ll.cid=l.cid and ll.dt<l.dt order by dt desc limit 0,1),
l.nvalue,
l.days,
l.dt,
if(l.uid=0,'сервер',u.name) user,
l.comment
from
log_contract_limit l
left join contract c on l.cid=c.id
left join user u on l.uid=u.id
where date(l.dt)=date(now())- interval 1 day order by l.cid, l.dt desc")
list.each do |row|
row.each do |val|
val="" if val == nil
report+="\"#{val.to_s.gsub("\"","").gsub(";","")}\";"
end
report+="\n"
end
fname=report_path+"daily-limit-report.#{(Date.today-1).to_s}.csv"
#Отправляем файлик на почту заинтересованным пользователям
Helper.send_file(File.basename(fname), Iconv.new('cp1251','utf-8').iconv(report), Helper.enc(mail_title), mail_from, mail_to.split)
#Пишем отчет в файлик для сохранения истории
w=File.open(fname,"w")
w.puts Iconv.new('cp1251','utf-8').iconv(report)
w.close
system("chmod 644 "+fname)
#Архивируем
Helper.zip_file(fname)
File.delete(fname)
end
end
def single_instance(&block)
if File.open($0).flock(File::LOCK_EX | File::LOCK_NB)
block.call
else
warn "Script #{$0} is already running"
end
end
class Helper
def self.enc(s)
return "=?windows-1251?B?"+[Iconv.new('cp1251','utf-8').iconv(s)].pack("m").gsub(/\r|\n/,"")+"?="
end
def self.send_file(filename, content, title, from, to)
msg = RMail::Message.new
part = RMail::Message.new
part.header.set('Content-Type', 'application/octet-stream')
part.header.set('Content-Disposition',
'attachment',
'filename' => filename)
part.header.set('Content-Transfer-Encoding', 'base64')
part.body=content.unpack('a*').pack('m')
msg.add_part(part)
msg.header.set("Subject", title)
msg.header.set("To", to.join(", "))
msg.header.set("From", from)
Net::SMTP.start('127.0.0.1') do |smtp|
smtp.send_message RMail::Serialize.write('',msg), from, to
end
end
def self.zip_file(filename)
Dir.chdir(File.dirname(filename))
filename=File.basename(filename)
Zip::ZipFile.open(filename + '.zip', Zip::ZipFile::CREATE) { |zipfile|
zipfile.get_output_stream(filename) { |f| f.write(File.read(filename))}
}
end
end
if __FILE__ == $0
single_instance do
Main.mainloop
end
end