Class: IParty::MaxMind

Inherits:
Object
  • Object
show all
Defined in:
lib/iparty/max_mind.rb,
lib/iparty/max_mind/result.rb,
lib/iparty/max_mind/database.rb,
lib/iparty/max_mind/lazy_reader.rb,
lib/iparty/max_mind/eager_reader.rb

Defined Under Namespace

Classes: Database, EagerReader, LazyReader, Result

Class Method Summary collapse

Class Method Details

.db(edition) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/iparty/max_mind.rb', line 10

def db edition
  edition = "GeoLite2-#{edition}" if edition.is_a?(Symbol)
  file = IParty.config.directory.join("#{edition}.mmdb")
  return unless file.exist?

  if ctn = IParty.config.singletons
    if ctn.is_a?(Proc)
      ctn = ctn.call
    elsif ctn == true
      ctn = IParty.config.init_singletons!
    end

    return ctn.fetch(edition) if ctn.key?(edition)
  end

  Database.new(file, reader: IParty.config.eager_load ? EagerReader : LazyReader).tap do |dbi|
    ctn[edition] ||= dbi if ctn
  end
end

.fetch_db_file!(edition, fetch_when = :always, verbose: false) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/iparty/max_mind.rb', line 83

def fetch_db_file! edition, fetch_when = :always, verbose: false
  target_file = IParty.config.directory.join("#{edition}.mmdb")
  return target_file unless reason = fetch_db_file_reason(target_file, fetch_when)

  with_transactional_update_directory do |temp_dir|
    warn "iparty: fetching #{reason}: #{target_file.basename}" if verbose
    IParty.config.url_to_mmdb.call(
      IParty.config.mirror.gsub(":edition", edition),
      temp_dir,
      IParty.config,
    )
  end
end

.fetch_db_file_reason(file, fetch_when = :always) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/iparty/max_mind.rb', line 66

def fetch_db_file_reason file, fetch_when = :always
  return fetch_when if fetch_when == :always
  return :missing unless file.exist?

  begin
    Database.new(file, reader: LazyReader)
  rescue Database::InvalidFileFormatError
    return :invalid
  end

  return unless fetch_when.is_a?(Numeric)

  ctime = file.ctime
  age = Time.now - ctime
  :expired unless fetch_when > age
end

.fetch_db_files!(fetch_when = :always, verbose: false) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/iparty/max_mind.rb', line 58

def fetch_db_files! fetch_when = :always, verbose: false
  with_transactional_update_directory do
    IParty.config.editions.each do |edition|
      fetch_db_file!(edition, fetch_when, verbose: verbose)
    end
  end
end

.lookup(edition, *args, close: true, **kw) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/iparty/max_mind.rb', line 30

def lookup edition, *args, close: true, **kw
  return unless mmdb = db(edition)

  mmdb.lookup(*args, **kw).tap do
    mmdb.close if close && !IParty.config.singletons
  end
end

.with_transactional_update_directoryObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/iparty/max_mind.rb', line 38

def with_transactional_update_directory
  temp_dir = IParty.config.directory.join(".updating")
  return yield(temp_dir) if @in_transaction

  begin
    @in_transaction = true
    temp_dir.mkpath
    yield(temp_dir)
  ensure
    @in_transaction = false
    temp_dir.glob("*.mmdb").each do |file|
      Database.new(file, reader: LazyReader)
      FileUtils.mv(file, IParty.config.directory)
    rescue Database::InvalidFileFormatError
      warn "iparty: ignoring invalid mmdb file: #{file}"
    end
    FileUtils.rm_rf(temp_dir)
  end
end