|
| 1 | +class IPServer |
| 2 | + |
| 3 | + API_URL = 'http://freeapi.ipip.net' |
| 4 | + |
| 5 | + def initialize(ip) |
| 6 | + @ip = ip |
| 7 | + end |
| 8 | + |
| 9 | + # returns: |
| 10 | + # [ |
| 11 | + # "中国", // 国家 |
| 12 | + # "天津", // 省会或直辖市(国内) |
| 13 | + # "天津", // 地区或城市 (国内) |
| 14 | + # "", // 学校或单位 (国内) |
| 15 | + # "联通", // 运营商字段 |
| 16 | + # ] |
| 17 | + |
| 18 | + def location |
| 19 | + @location ||= begin |
| 20 | + cached_request |
| 21 | + end |
| 22 | + end |
| 23 | + |
| 24 | + # https://www.ipip.net/api.html 已升级为收费 |
| 25 | + # curl "http://ipapi.ipip.net/find?addr=118.28.8.8" -H "Token: my_token" |
| 26 | + # NOTICE: ipip由于受到攻击,把ua为Ruby开头的封掉了,RestClient默认为Ruby的Ua |
| 27 | + Header = {"Token" => my_token, "User-Agent" => "curl"} |
| 28 | + ApiUrl = "http://ipapi.ipip.net/find" |
| 29 | + IpExpireTime = 60.days |
| 30 | + |
| 31 | + def cached_request |
| 32 | + redis_get_ip(@ip) or \ |
| 33 | + begin |
| 34 | + url = "#{ApiUrl}?addr=#{@ip}" |
| 35 | + res = JSON.parse RestClient::Request.execute(method: :get, url: url, headers: Header, timeout: 1) |
| 36 | + data = res['data'][0..4] |
| 37 | + redis |
| 38 | + rescue Exception => e |
| 39 | + e.error_log("IPIP ERROR: #{@ip}") |
| 40 | + ["", "", "", "", ""].freeze |
| 41 | + end |
| 42 | + end |
| 43 | + |
| 44 | + def redis_set_ip(ip,data) |
| 45 | + redis.set("IPIP:#{ip}", data.to_json, ex: IpExpireTime) |
| 46 | + end |
| 47 | + def redis_get_ip(ip) |
| 48 | + redis.get("IPIP:#{ip}").presence.try do |data| |
| 49 | + return JSON.parse(data) rescue nil |
| 50 | + end |
| 51 | + end |
| 52 | + def self.ipip_status |
| 53 | + JSON.parse RestClient::Request.execute(:method => :get, :url => "#{ApiUrl}_status", :headers => Header, :timeout => 1) |
| 54 | + end |
| 55 | + |
| 56 | + def unknown? |
| 57 | + location.all?(&:blank?) |
| 58 | + end |
| 59 | + |
| 60 | + def local? |
| 61 | + ["局域网"].include?(location.first) |
| 62 | + end |
| 63 | + |
| 64 | + def human_name |
| 65 | + if unknown? |
| 66 | + '未知IP' |
| 67 | + elsif local? |
| 68 | + "局域网" |
| 69 | + else |
| 70 | + location.reject { |element| element.eql?('中国') }.uniq.join |
| 71 | + end |
| 72 | + end |
| 73 | + |
| 74 | + # TODO: 和 phone_info 表里的省名称一致 |
| 75 | + def province |
| 76 | + (unknown? || local?) ? "" : location[1] |
| 77 | + end |
| 78 | + |
| 79 | + # TODO: 和 phone_info 表里的市名称一致 |
| 80 | + def city |
| 81 | + (unknown? || local?) ? "" : location[2] |
| 82 | + end |
| 83 | + |
| 84 | + def service_provider |
| 85 | + (unknown? || local?) ? "" : location[4] |
| 86 | + end |
| 87 | + def redis |
| 88 | + $imv4_redis |
| 89 | + end |
| 90 | + |
| 91 | +end |
0 commit comments