Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/ruby
- require 'date'
- require 'tempfile'
- require 'optparse'
- require 'rubygems'
- require 'zip'
- require 'net/ftp'
- # Домен
- $domain = 'ftp.zakupki.gov.ru'
- # Начальная часть пути. Далее идет разветвление на реестры.
- $base_path = '/fcs_regions/Tatarstan_Resp/'
- # Логин и пароль на ftp
- $user = 'free'
- $password = 'free'
- # Захардкоженые параметры
- $path = nil
- $date_period = nil
- $download_path = '/tmp/'
- $queries = []
- # Проверяет по имени файла, подходит ли он под даты.
- # Файлы на ftp ООС в наименовании содержат две даты,
- # в формате YYYYMMDD??_YYYYMMDD??, цепляемся за них.
- def matches_period?(zip_name)
- if zip_name =~ /(20\d{6})\d\d_(20\d{6})\d\d_\d+\.xml\.zip/
- file_from = Date.parse($1)
- file_to = Date.parse($2)
- if ($date_period.include?(file_from) or
- $date_period.include?(file_to) or
- (file_from < $date_period.begin and file_to > $date_period.end))
- return true
- end
- end
- false
- end
- # Проверяет, содержит ли файл искомые подстроки.
- def file_content_matches?(content)
- $queries.any? { |q| content.upcase.include?(q.upcase) }
- end
- # Обрабатывает zip-файл. Возвращает список подходящих файлов.
- def process_zip_file(zip_file)
- found_files = []
- Zip::File.open(zip_file.path) do |zip_iter|
- zip_iter.each do |entry|
- content = entry.get_input_stream.read.force_encoding('UTF-8')
- if file_content_matches?(content)
- File.write("#{$download_path}/#{entry.name}", content)
- found_files << entry.name
- end
- end
- end
- found_files
- end
- # Парсим аргументы программы
- OptionParser.new do |opts|
- opts.banner = %{\
- Скрипт для поиска на FTP ЕИС xml-файлов с нужным содержимым.
- Использование: ruby script-name.rb ПАРАМЕТРЫ.
- }
- opts.on('--path PATH',
- 'Конец директории на ftp (например, contracts/currMonth).') do |path|
- $path = path
- end
- opts.on('--period FROM..UNTIL',
- 'Интересующий временной период, разделенный `..`, например ' +
- '2016-01-01..2016-05-27. Опциональный.') do |period|
- from, thru = period.split('..')
- $date_period = Date.parse(from)..Date.parse(thru)
- end
- opts.on('--download PATH',
- 'Директория, в которую будут качаться xml-файлы. ' +
- "Если не задан - в #{$download_path}.") do |path|
- $download_path = path
- end
- opts.on('--queries one,two,three', Array,
- 'Искомые в файлах подстроки (регистр не важен). ' +
- 'Должны быть разделены запятыми.') do |qs|
- $queries += qs
- end
- end.parse!
- # Некоторые аргументы требуются
- if $path.nil? or $queries.empty?
- raise OptionParser::MissingArgument
- end
- # Начальная информация
- if $date_period.nil?
- puts "Ищем файлы в #{$path} за любой период."
- else
- puts "Ищем файлы в #{$path} за #{$date_period.begin} - #{$date_period.end}."
- end
- puts "Скачиваем в #{$download_path}, параметры поиска: #{$queries.join ', '}"
- Net::FTP.open($domain) do |ftp|
- ftp.passive = true
- ftp.login($user, $password)
- ftp.chdir($base_path)
- ftp.chdir($path)
- zip_files_list = ftp.nlst('*.zip')
- tmp_zip_file = Tempfile.new(['archive', '.zip'])
- begin
- zip_files_list.each do |zip_name|
- if $date_period.nil? or matches_period?(zip_name)
- print "Обработка #{zip_name}... ".ljust(79) + "\r"
- $stdout.flush
- ftp.getbinaryfile(zip_name, tmp_zip_file)
- found_files = process_zip_file(tmp_zip_file)
- unless found_files.empty?
- found_files.each do |fname|
- puts "-> #{fname}".ljust(80)
- end
- end
- end
- end
- puts ''.ljust(80)
- ensure
- tmp_zip_file.close
- tmp_zip_file.unlink
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement