Class: IPLookup::DB

Inherits:
Object
  • Object
show all
Defined in:
lib/ip_lookup/db.rb

Constant Summary collapse

DEFAULT_UPDATE_PERIOD_IN_DAYS =
30
DEFAULT_UPDATE_URI =
"https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(silent_exceptions) ⇒ DB

Returns a new instance of DB.



13
14
15
# File 'lib/ip_lookup/db.rb', line 13

def initialize(silent_exceptions)
  @silent_exceptions = silent_exceptions
end

Instance Attribute Details

#silent_exceptionsObject (readonly)

Returns the value of attribute silent_exceptions.



11
12
13
# File 'lib/ip_lookup/db.rb', line 11

def silent_exceptions
  @silent_exceptions
end

Class Method Details

.db_ageObject



83
84
85
# File 'lib/ip_lookup/db.rb', line 83

def db_age
  (Time.now - File.mtime(db_path)) / (24 * 60 * 60)
end

.db_exists?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/ip_lookup/db.rb', line 79

def db_exists?
  File.file? db_path
end

.db_pathObject



87
88
89
90
91
92
93
# File 'lib/ip_lookup/db.rb', line 87

def db_path
  if Gem.loaded_specs["ip_lookup"]
    File.join(Gem.loaded_specs["ip_lookup"].full_gem_path, "/support/geolite-city.mmdb")
  else
    File.join(File.expand_path("../..", File.dirname(__FILE__)), "/support/geolite-city.mmdb")
  end
end

.fetch_db(update_uri) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/ip_lookup/db.rb', line 44

def fetch_db(update_uri)
  uri = URI(update_uri)

  response = Net::HTTP.get(uri)

  sio_response = StringIO.new(response)
  gz = Zlib::GzipReader.new(sio_response)
  gz.read
end

.flock(file) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ip_lookup/db.rb', line 62

def flock(file)
  # return and don't update db if file is locked, because db is already been updated
  return unless file.flock(File::LOCK_EX | File::LOCK_NB)

  if file.flock(File::LOCK_EX)
    begin
      yield file
    ensure
      file.flock(File::LOCK_UN)
    end
  end
end

.mutexObject



23
24
25
# File 'lib/ip_lookup/db.rb', line 23

def self.mutex
  @mutex ||= Mutex.new
end

.save_db(result) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/ip_lookup/db.rb', line 54

def save_db(result)
  File.open(db_path, 'w') do |file|
    flock(file) do |f|
      f.write(result)
    end
  end
end

.update(update_period: DEFAULT_UPDATE_PERIOD_IN_DAYS, update_uri: DEFAULT_UPDATE_URI) ⇒ Object



38
39
40
41
42
# File 'lib/ip_lookup/db.rb', line 38

def update(update_period: DEFAULT_UPDATE_PERIOD_IN_DAYS, update_uri: DEFAULT_UPDATE_URI)
  return unless update_db? update_period

  save_db fetch_db(update_uri)
end

.update_db?(update_period) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/ip_lookup/db.rb', line 75

def update_db?(update_period)
  !db_exists? || (update_period >= 0 && db_age > update_period)
end

Instance Method Details

#lookup(ip_address) ⇒ Object



17
18
19
20
21
# File 'lib/ip_lookup/db.rb', line 17

def lookup(ip_address)
  db.lookup ip_address
rescue Errno::ENOENT
  raise DBFileNotFoundError, "Couldn't find DB file. Please update DB before using lookup." unless silent_exceptions
end