Module: PincodeFinder
- Defined in:
- lib/pincode_finder.rb,
lib/pincode_finder/config.rb,
lib/pincode_finder/version.rb,
lib/pincode_finder/github_client.rb
Defined Under Namespace
Classes: Config, GitHubClient
Constant Summary collapse
- DATA_FILE =
File.("../data/pincode_data_optimized.json.gz", __dir__)
- DETAILS_HASH =
"{ district: <district>, state: <state>}".freeze
- VERSION =
"0.1.4"
Class Method Summary collapse
- .add_pincode(pincode, input_details) ⇒ Object
- .config ⇒ Object
- .configure {|config| ... } ⇒ Object
- .delete_pincode(pincode) ⇒ Object
- .find(pincode) ⇒ Object
- .input_details_validation(data, input_details) ⇒ Object
- .load_data ⇒ Object
- .normalize_and_filter(input_details) ⇒ Object
- .save_data(json) ⇒ Object
- .sync_to_github(data) ⇒ Object
- .update_pincode(pincode, input_details) ⇒ Object
- .validate_pincode(pincode, input_details) ⇒ Object
- .verify_pincode(pincode) ⇒ Object
Class Method Details
.add_pincode(pincode, input_details) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pincode_finder.rb', line 36 def self.add_pincode(pincode, input_details) pincode = pincode.to_s input_details = normalize_and_filter(input_details) data = load_data record = data[pincode] return { status: "failure", error: "Pincode already present in the directory" } unless record.nil? verified, error = validate_pincode(pincode, input_details) return { status: "failure", error: error } unless error.nil? data[pincode] = input_details.merge("verified" => verified) save_data(data) sync_to_github(data) { status: "success", data: data[pincode], error: nil } end |
.config ⇒ Object
12 13 14 |
# File 'lib/pincode_finder/config.rb', line 12 def self.config @config ||= Config.new end |
.configure {|config| ... } ⇒ Object
16 17 18 |
# File 'lib/pincode_finder/config.rb', line 16 def self.configure yield(config) end |
.delete_pincode(pincode) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/pincode_finder.rb', line 121 def self.delete_pincode(pincode) pincode = pincode.to_s data = load_data record = data[pincode] return { status: "failure", error: "pincode not found" } unless record data.delete(pincode) save_data(data) sync_to_github(data) { status: "success", data: {}, error: nil } end |
.find(pincode) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/pincode_finder.rb', line 15 def self.find(pincode) pincode = pincode.to_s data = load_data record = data[pincode] if record { pincode: pincode, state: record["state"], district: record["district"], verified: record["verified"] || true } else { error: "Pincode not found", message: "You can add it using: PincodeFinder.add_pincode(#{pincode}, #{DETAILS_HASH})" } end end |
.input_details_validation(data, input_details) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/pincode_finder.rb', line 140 def self.input_details_validation(data, input_details) input_state = input_details["state"].to_s.titleize input_district = input_details["district"].to_s.titleize api_state = data["State"].to_s.titleize api_district = data["District"].to_s.titleize api_division = data["Division"].to_s.titleize return [false, "Incorrect state. Allowed: #{api_state}"] unless input_state == api_state unless input_district == api_district || input_district == api_division return [ false, "Incorrect district. Allowed: #{api_district} or #{api_division}" ] end [true, nil] end |
.load_data ⇒ Object
160 161 162 |
# File 'lib/pincode_finder.rb', line 160 def self.load_data Zlib::GzipReader.open(DATA_FILE) { |gz| JSON.parse(gz.read) } end |
.normalize_and_filter(input_details) ⇒ Object
172 173 174 175 176 |
# File 'lib/pincode_finder.rb', line 172 def self.normalize_and_filter(input_details) input_details .transform_keys { |k| k.to_s.downcase } .slice("district", "state") end |
.save_data(json) ⇒ Object
164 165 166 167 168 169 170 |
# File 'lib/pincode_finder.rb', line 164 def self.save_data(json) json_string = JSON.pretty_generate(json) Zlib::GzipWriter.open(DATA_FILE) do |gz| gz.write(json_string) end end |
.sync_to_github(data) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/pincode_finder.rb', line 178 def self.sync_to_github(data) Thread.new do begin client = GitHubClient.new remote = client.get_file_with_sha sha = remote[:sha] client.update_file(data, sha) rescue StandardError nil end end end |
.update_pincode(pincode, input_details) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/pincode_finder.rb', line 99 def self.update_pincode(pincode, input_details) pincode = pincode.to_s input_details = normalize_and_filter(input_details) data = load_data record = data[pincode] return { status: "failure", error: "pincode not found" } unless record verified, error = validate_pincode(pincode, input_details) return { status: "failure", error: error } unless error.nil? data[pincode] = input_details.merge("verified" => verified) save_data(data) sync_to_github(data) { status: "success", data: data[pincode], error: nil } end |
.validate_pincode(pincode, input_details) ⇒ Object
61 62 63 64 65 66 67 68 69 |
# File 'lib/pincode_finder.rb', line 61 def self.validate_pincode(pincode, input_details) verified, api_data = verify_pincode(pincode) return [false, nil] unless verified status, error = input_details_validation(api_data, input_details) return [false, error] unless status [verified, nil] end |
.verify_pincode(pincode) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/pincode_finder.rb', line 71 def self.verify_pincode(pincode) begin uri = URI("https://api.postalpincode.in/pincode/#{pincode}") response = Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: 3, read_timeout: 3) do |http| http.get(uri.request_uri) end return [false, nil] unless response.is_a?(Net::HTTPSuccess) json = JSON.parse(response.body) rescue nil return [false, nil] unless json.is_a?(Array) && json[0].is_a?(Hash) status = json[0]["Status"] return [false, nil] unless status == "Success" po = json[0]["PostOffice"] return [false, nil] unless po.is_a?(Array) && po[0].is_a?(Hash) details = po[0].slice("Division", "District", "State") [true, details] rescue StandardError [false, nil] end end |