179GeolocationwithMaxMindsGeoIPandthegeoipcityRubyGemInstall

Geolocation with MaxMind's GeoIP and the geoip-city RubyGem

Ruby posted over 3 years ago by christian

http://snippets.aktagon.com/snippets/179-Geolocation-with-MaxMind-s-GeoIP-and-the-geoip-city-RubyGemInstall GeoIP library

 wget http<span class="UserDefinedConstant"><span class="UserDefinedConstant">:</span>/</span><span class="Operator">/</span>www.<span class="FunctionName">maxmind</span>.<span class="FunctionName">com</span><span class="Operator">/</span>download<span class="Operator">/</span>geoip<span class="Operator">/</span>api<span class="Operator">/</span>c<span class="Operator">/</span><span class="LibraryClassType">GeoIP</span>.<span class="FunctionName">tar</span>.<span class="FunctionName">gz</span> tar <span class="Operator">-</span>zxvf <span class="LibraryClassType">GeoIP</span>.<span class="FunctionName">tar</span>.<span class="FunctionName">gz</span> cd <span class="Variable">GeoIP</span> .<span class="Operator">/</span>configure <span class="Operator">-</span><span class="Operator">-</span>prefix<span class="Operator">=</span><span class="String"><span class="String">/</span></span><span class="String">opt</span><span class="String"><span class="String">/</span></span><span class="Variable">GeoIP</span> make <span class="Operator">&&</span> sudo make install 

Install the geoip-city gem

 gem install geoip_city <span class="Operator">-</span><span class="Operator">-</span> <span class="Operator">-</span><span class="Operator">-</span>with<span class="Operator">-</span>geoip<span class="Operator">-</span>dir<span class="Operator">=</span><span class="String"><span class="String">/</span></span><span class="String">opt</span><span class="String"><span class="String">/</span></span><span class="Variable">GeoIP</span> 

Test the bindings

 curl <span class="Operator">-</span><span class="Variable">O</span> http<span class="UserDefinedConstant"><span class="UserDefinedConstant">:</span>/</span><span class="Operator">/</span>geolite.<span class="FunctionName">maxmind</span>.<span class="FunctionName">com</span><span class="Operator">/</span>download<span class="Operator">/</span>geoip<span class="Operator">/</span>database<span class="Operator">/</span><span class="LibraryClassType">GeoLiteCity</span>.<span class="FunctionName">dat</span>.<span class="FunctionName">gz</span> gunzip <span class="LibraryClassType">GeoLiteCity</span>.<span class="FunctionName">dat</span>.<span class="FunctionName">gz</span> 

Fire up IRB and try the following code:

 <span class="Keyword">require</span> <span class="String"><span class="String">'</span>rubygems<span class="String">'</span></span> <span class="Keyword">require</span> <span class="String"><span class="String">'</span>geoip_city<span class="String">'</span></span> db <span class="Operator">=</span> <span class="LibraryClassType">GeoIPCity</span>::<span class="FunctionName">Database</span>.<span class="FunctionName">new</span>(<span class="String"><span class="String">'</span>GeoLiteCity.dat<span class="String">'</span></span>) result <span class="Operator">=</span> db.<span class="FunctionName">look_up</span>(<span class="String"><span class="String">'</span>192.143.34.23<span class="String">'</span></span>) p result 

Another option is to use hostip.info’s database, as described in this article.

Create a wrapper

 <span class="Keyword">require</span> <span class="String"><span class="String">'</span>rubygems<span class="String">'</span></span> <span class="Keyword">require</span> <span class="String"><span class="String">'</span>geoip_city<span class="String">'</span></span> <span class="Keyword">require</span> <span class="String"><span class="String">'</span>ostruct<span class="String">'</span></span>  <span class="Keyword">class</span> <span class="TypeName">Location<span class="InheritedClass"> <span class="InheritedClass"><</span> OpenStruct</span></span> <span class="Keyword">end</span>  <span class="Keyword">class</span> <span class="TypeName">GeoIP</span>   <span class="Keyword">class</span> <span class="TypeName"><span class="Variable"><span class="Variable"><<</span> self</span></span>     <span class="Variable">DB</span> <span class="Operator">=</span> <span class="LibraryClassType">GeoIPCity</span>::<span class="FunctionName">Database</span>.<span class="FunctionName">new</span>(<span class="String"><span class="String">'</span>GeoLiteCity.dat<span class="String">'</span></span>)      <span class="Keyword">def</span> <span class="FunctionName">lookup</span>(<span class="FunctionArgument">ip</span>)       <span class="Keyword">if</span> result <span class="Operator">=</span> <span class="Variable">DB</span>.<span class="FunctionName">look_up</span>(ip)         location <span class="Operator">=</span> <span class="LibraryClassType">Location</span>.<span class="FunctionName">new</span>  <span class="LineComment">        <span class="LineComment">#</span></span> <span class="LineComment">        <span class="LineComment">#</span> {:country_code=>"FR", :country_code3=>"FRA", :country_name=>"France", :latitude=>46.0, :longitude=>2.0}</span> <span class="LineComment">        <span class="LineComment">#</span></span>         result.<span class="FunctionName">each</span> <span class="Keyword">do </span>|<span class="Variable">key</span>, <span class="Variable">val</span>|            location.<span class="FunctionName">send</span> <span class="String"><span class="String">"</span><span class="String"><span class="String">#{</span>key<span class="String">}</span></span>=<span class="String">"</span></span>, val         <span class="Keyword">end</span>       <span class="Keyword">end</span>        location     <span class="Keyword">end</span>   <span class="Keyword">end</span> <span class="Keyword">end</span> 

Add some Rails caching

Combined with the above code this will give you cached IP lookups:

 <span class="Keyword">class</span> <span class="TypeName">GeoIP</span>    <span class="Keyword">class</span> <span class="TypeName"><span class="Variable"><span class="Variable"><<</span> self</span></span>     <span class="Keyword">def</span> <span class="FunctionName">lookup_with_caching</span>(<span class="FunctionArgument">ip</span>)       <span class="LibraryClassType">Rails</span>.<span class="FunctionName">cache</span>.<span class="FunctionName">fetch</span>(ip, <span class="UserDefinedConstant"><span class="UserDefinedConstant">:</span>expires_in</span> => <span class="Number">1</span>.<span class="FunctionName">month</span>) <span class="Keyword">do </span>         <span class="FunctionName">lookup_without_caching</span>(ip)       <span class="Keyword">end</span>     <span class="Keyword">end</span>      alias_method_chain <span class="UserDefinedConstant"><span class="UserDefinedConstant">:</span>lookup</span>, <span class="UserDefinedConstant"><span class="UserDefinedConstant">:</span>caching</span>   <span class="Keyword">end</span> <span class="Keyword">end</span> 

Alternatives

If you’re unable to install the C extension you might want to have a look at the geoip gem, which is a pure Ruby library that can read the MaxMind’s geoip database. It’s slower but easier to install: http://geoip.rubyforge.org/



原文地址:https://www.cnblogs.com/lexus/p/2146351.html