# frozen_string_literal: true require 'japan_etc/database_provider/base' require 'japan_etc/tollbooth' require 'japan_etc/util' require 'faraday' require 'pdf-reader' module JapanETC module DatabaseProvider class NEXCO < Base include Util # NEXCO East # URL = 'https://www.driveplaza.com/traffic/tolls_etc/etc_area/pdf/all01.pdf' # NEXCO Central # NOTE: This PDF has issues with text encoding # URL = 'https://highwaypost.c-nexco.co.jp/faq/etc/use/documents/etcriyoukanouic.pdf' # NEXCO West URL = 'https://www.w-nexco.co.jp/etc/maintenance/pdfs/list01.pdf' WHITESPACE = /[\s ]/.freeze TOLLBOOTH_LINE_PATTERN = / \A (?: #{WHITESPACE}{,10}(?[^#{WHITESPACE}\d(【][^#{WHITESPACE}]*)#{WHITESPACE}+ | #{WHITESPACE}{,10}(?:[(【][^#{WHITESPACE}]+)#{WHITESPACE}+ # Obsolete road name | #{WHITESPACE}{10,} ) (?: (?[^#{WHITESPACE}\d(【][^#{WHITESPACE}]*) #{WHITESPACE}+ )? (?\d{2}#{WHITESPACE}+\d{3}\b.*?) (?: ※ (?.+?) #{WHITESPACE}* )? \z /x.freeze IDENTIFIER_PATTERN = /\b(\d{2})#{WHITESPACE}+(\d{3})\b/.freeze attr_reader :current_road_name, :current_route_name, :current_tollbooth_name def fetch_tollbooths lines.flat_map { |line| parse_line(line) }.compact end def parse_line(line) match = line.match(TOLLBOOTH_LINE_PATTERN) return unless match if match[:road_name] @current_road_name, @current_route_name = extract_route_name_from_road_name(match[:road_name]) @current_road_name = canonicalize(@current_road_name) end @current_tollbooth_name = match[:tollbooth_name] if match[:tollbooth_name] identifiers = match[:identifiers].scan(IDENTIFIER_PATTERN) identifiers.map do |identifier| Tollbooth.create( road_number: identifier.first, tollbooth_number: identifier.last, road_name: current_road_name, route_name: current_route_name, name: current_tollbooth_name, note: match[:note] ) end end def extract_route_name_from_road_name(road_name) road_name = normalize(road_name) match = road_name.match(/\A(?.+?)(?\d+号.+)?\z/) road_name = match[:road_name].sub(/高速\z/, '高速道路') [road_name, match[:route_name]] end def canonicalize(road_name) road_name = '首都圏中央連絡自動車道' if road_name == '首都圏中央連絡道' road_name = road_name.sub(/高速\z/, '高速道路') road_name end def lines pdf.pages.flat_map { |page| page.text.each_line.map(&:chomp).to_a } end def pdf response = Faraday.get(URL) PDF::Reader.new(StringIO.new(response.body)) end end end end