Skip to content

Instantly share code, notes, and snippets.

@IvikGH
Created April 27, 2016 12:47
Show Gist options
  • Save IvikGH/f4e2dac7d05934527ac3eb8f3c370e28 to your computer and use it in GitHub Desktop.
Save IvikGH/f4e2dac7d05934527ac3eb8f3c370e28 to your computer and use it in GitHub Desktop.
postfix2
require_relative 'parser'
require_relative 'sender'
class Organizer
attr_reader :filename
attr_accessor :jsons
def initialize(filename)
@filename = filename
@jsons = []
end
def process_bounces
loop do
get_bounces_json
while @jsons.size >= 10
result = Sender.new.process(jsons[0,10])
@jsons = @jsons.drop(10) if result
end
sleep 5
end
end
def bounce?(line)
!(/status=bounced/.match(line).nil?)
end
def get_bounces_json
file = File.new(filename)
parser = Parser.new
file.each do |line|
jsons << parser.parse_bounce(line) if bounce?(line)
end
File.open(filename,"w") { |file| file.write('') }
end
end
require_relative '../organizer'
describe Organizer do
let(:bounce_line) { 'May 24 12:51:53 TEST postfix/smtp[7203]: 1746B93F7F: to=<[email protected]>, orig_to=<root@localhost>, relay=localhost.lab.ru[194.135.30.57], delay=5, status=bounced (host localhost.lab.ru[194.135.30.57] said: 550 5.7.1 <[email protected]>... Relaying denied (in reply to RCPT TO command))' }
let(:not_bounce_line) { 'May 24 12:51:53 TEST postfix/smtp[7203]: 1746B93F7F: to=<[email protected]>, orig_to=<root@localhost>, relay=localhost.lab.ru[194.135.30.57], delay=5, status=deffered (host localhost.lab.ru[194.135.30.57] said: 550 5.7.1 <[email protected]>... Relaying denied (in reply to RCPT TO command))' }
let(:filename) {'spec/maillog_data'}
let(:organizer) { Organizer.new(filename) }
it 'bounce? detects line with "status=bounced"' do
expect(organizer.bounce?(bounce_line)).to be_truthy
end
it 'bounce? doesnt detect line without "status=bounced"' do
expect(organizer.bounce?(not_bounce_line)).to be_falsey
end
it 'gets data with #get_bounces_json' do
before = organizer.jsons.size
organizer.get_bounces_json
after = organizer.jsons.size
expect(before).to be < after
end
it 'after #get_bounces_json data file has no data' do
organizer.get_bounces_json
line_count = `wc -l "#{filename}"`.strip.split(' ')[0].to_i
expect(line_count).to eq 0
end
end
require 'json'
class Parser
attr_reader :regex, :keys
def initialize
@regex = /(?<date>[\w\s:]+)\sTEST\spostfix\/
(?<port>[\w\[\]]+):\s
(?<ps_id>[A-Z0-9]+):\s
to=<(?<to>[\w@\.-]+)>,\s
orig_to=<(?<orig_to>[\w@\.-]+)>,\s
relay=(?<relay>[\w@\.-\[\]]+),\s
delay=(?<delay>\d+),\sstatus=bounced\s.+?
said:\s(?<description>.+?)\){2}/x
@keys = [:date, :port, :ps_id, :to, :orig_to, :relay, :delay, :description]
end
def parse_bounce(line)
match = regex.match(line)
raise "Some keys missing in log line" unless match
convert_to_json(match, keys) if match
end
def convert_to_json(match, keys)
bounce = {}
keys.each do |key|
bounce[key] = match[key]
end
bounce.to_json
end
end
require_relative '../parser'
require 'json'
describe Parser do
let(:bounce_line) { 'May 24 12:51:53 TEST postfix/smtp[7203]: 1746B93F7F: to=<[email protected]>, orig_to=<root@localhost>, relay=localhost.lab.ru[194.135.30.57], delay=5, status=bounced (host localhost.lab.ru[194.135.30.57] said: 550 5.7.1 <[email protected]>... Relaying denied (in reply to RCPT TO command))' }
let(:incorrect_bounce_line) { 'May 24 12:57:15 TEST postfix/smtp[7211]: 4182593F7F: to=<[email protected]>, relay=localhost.lab.ru[194.135.30.57], delay=11, status=bounced (host localhost.lab.ru[194.135.30.57] said: 550 5.7.1 <[email protected]>... Relaying denied (in reply to RCPT TO command))' }
let(:parser) { Parser.new }
it '#parse_bounce and #convert_to_json parses lines correctly' do
manual_parser = Parser.new
manual_parser.parse_bounce(bounce_line)
match = manual_parser.regex.match(bounce_line)
bounce = {}
manual_parser.keys.each do |key|
bounce[key] = match[key]
end
manual_json = bounce.to_json
method_json = parser.parse_bounce(bounce_line)
expect(manual_json == method_json).to be_truthy
end
it 'raise "Some keys missing in log line" if log line doesnt have all fields' do
expect { parser.parse_bounce(incorrect_bounce_line) }
.to raise_error('Some keys missing in log line')
end
end
require_relative './organizer'
Organizer.new(ARGV[0]).process_bounces
class Sender
def process(jsons)
p jsons
if true # < < < true подтверждение об успешной доставке
return true
else
false # < < < true подтверждение о cбое доставки
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment