glebtv_ipgeobase 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cc791c423863bb21dfc8e6da68897ff1f0d73135
4
+ data.tar.gz: 2af05240695b52cc36bb1d4497b78369a1843c85
5
+ SHA512:
6
+ metadata.gz: 0f0919f3d4cee533430937e34aec13e83c974b718bbd3cdaed805293acae1096e1b93c226cb5a46ae9c63d46f764b04657835c6590813a11afad34b62c188fdb
7
+ data.tar.gz: c2c9680db4a2569ca48a45d3269163f83b93ccd839976627523be8aad074cdb261693ef6c0118e565326127b51639431e1b4714e2edc814ae88f7442ee674afb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ipgeobase.gemspec
4
+ gemspec
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ glebtv_ipgeobase (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ rake (10.4.2)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler
16
+ glebtv_ipgeobase!
17
+ rake
@@ -0,0 +1,39 @@
1
+ = IPGeoBase
2
+
3
+ Архив с сайта http://ipgeobase.ru, содержащий базу местонахождений российских (с точностью до города), украинских (с точностью до города) и европейских (с точностью до страны) ip-адресов.
4
+
5
+ == Installation
6
+
7
+ (1) Add to Gemfile:
8
+ gem 'ipgeobase', github: 'glebtv/ipgeobase'
9
+ (2) Install required gems:
10
+ bundle install
11
+ (3) Create models
12
+ rails g ipgeobase:migration
13
+ (4) Run migration
14
+ rake db:migrate
15
+
16
+ == Upload new database
17
+
18
+ * Update cities and regions from FILE or by URL(default)
19
+
20
+ rake ipgeobase:cities
21
+
22
+ * Update geo ips from FILE or by URL(default)
23
+
24
+ rake ipgeobase:ips
25
+
26
+ == Add relation for models
27
+
28
+ module User < ActiveRecord::Base
29
+ belongs_to_region
30
+ end
31
+
32
+ По умолчанию цепляется к полю region_id:integer в модели. Можно кастомизировать следующим образом:
33
+ belongs_to_region :foreign_key => :reg_id
34
+
35
+ == Methods
36
+
37
+ После того, как выполнены все предыдущие шаги можно искать регион по IP адресу:
38
+ Ipgeobase::find_region_by_ip( '95.170.177.170' )
39
+ => #<Ipgeobase::Region id: 576, name: "Красноярск", ancestry: "1/296/485", names_depth_cache: "Россия/Сибирский федеральный округ/Красноярский кра...", region_id: 1428, ...>
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ module Ipgeobase
2
+ class City < ActiveRecord::Base
3
+ self.table_name = "ipgeobase_cities"
4
+ belongs_to :country, class_name: 'Ipgeobase::Country'
5
+ validates_presence_of :city, :country
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Ipgeobase
2
+ class Country < ActiveRecord::Base
3
+ self.table_name = "ipgeobase_countries"
4
+ has_many :cities, class_name: 'Ipgeobase::City'
5
+ validates_presence_of :name
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Ipgeobase
2
+ class Ip < ActiveRecord::Base
3
+ self.table_name = "ipgeobase_ips"
4
+ belongs_to :city, class_name: 'Ipgeobase::City'
5
+ validates_presence_of :start_ip, :end_ip, :city_id
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ipgeobase/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "glebtv_ipgeobase"
7
+ s.version = Ipgeobase::VERSION
8
+ s.authors = ["glebtv", "Avramov Vsevolod"]
9
+ s.email = ["glebtv@gmail.com", "gsevka@gmail.com"]
10
+ s.homepage = "http://github.com/glebtv/ipgeobase"
11
+ s.summary = "upload archive from IPGeoBase.ru to your project"
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+
18
+ s.required_ruby_version = '>= 2.0.0'
19
+
20
+ s.add_development_dependency 'bundler'
21
+ s.add_development_dependency 'rake'
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Ipgeobase
5
+ module Generators
6
+ class MigrationGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ desc "Generates migration for Ipgeobase models"
10
+
11
+ def self.source_root
12
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
13
+ end
14
+
15
+ def self.next_migration_number(dirname)
16
+ Time.now.strftime("%Y%m%d%H%M%S")
17
+ end
18
+
19
+ def create_ipgeobase_migration
20
+ migration_template "migration.rb", File.join('db/migrate', "create_ipgeobase.rb")
21
+ end
22
+
23
+ protected
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,34 @@
1
+ class CreateIpgeobase < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :ipgeobase_countries do |t|
4
+ t.string :name
5
+ t.string :code
6
+ end
7
+
8
+ create_table :ipgeobase_cities do |t|
9
+ t.string :city
10
+ t.string :region
11
+ t.string :district
12
+ t.float :lat
13
+ t.float :lon
14
+ t.integer :country_id
15
+ t.foreign_key :ipgeobase_countries, column: :country_id
16
+ end
17
+
18
+ create_table :ipgeobase_ips, :id => false do |t|
19
+ t.integer :start_ip, :limit => 8
20
+ t.integer :end_ip, :limit => 8
21
+ t.integer :city_id
22
+ t.foreign_key :ipgeobase_cities, column: :city_id
23
+ end
24
+
25
+ add_index :ipgeobase_ips, [:start_ip]
26
+ add_index :ipgeobase_ips, [:city_id], name: "index_ipgeobase_ips_on_city_id"
27
+ end
28
+
29
+ def self.down
30
+ drop_table :ipgeobase_ips
31
+ drop_table :ipgeobase_cities
32
+ drop_table :ipgeobase_countries
33
+ end
34
+ end
@@ -0,0 +1,2 @@
1
+ require 'ipgeobase'
2
+
@@ -0,0 +1,23 @@
1
+ require "ipgeobase/version"
2
+ require 'ipaddr'
3
+
4
+ if defined? Rails::Engine
5
+ require 'ipgeobase/engine'
6
+ end
7
+
8
+ module Ipgeobase
9
+ class << self
10
+ def find_region_by_ip(user_ip)
11
+ long = ip2long(user_ip)
12
+ Ipgeobase::Ip.select( <<-SELECT ).where( "start_ip <= #{long}" ).order( 'start_ip DESC' ).first.try(:city)
13
+ CASE WHEN #{long} <= end_ip
14
+ THEN city_id
15
+ ELSE NULL END AS city_id
16
+ SELECT
17
+ end
18
+
19
+ def ip2long(ip)
20
+ IPAddr.new(ip, Socket::AF_INET).to_i
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ class << ActiveRecord::Base
2
+
3
+ def belongs_to_region options={}
4
+ belongs_to :region, :class_name => "Ipgeobase::Region", :foreign_key => :region_id, :primary_key => (options[:primary_key] || :id)
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ module Ipgeobase
2
+ class Engine < ::Rails::Engine
3
+ rake_tasks do
4
+ load "ipgeobase/tasks.rake"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ module Ipgeobase
4
+ module Task
5
+ def self.obtain_content_by_filename(filename)
6
+ if defined? Rails
7
+ file = ::Rails.root.join('tmp', filename)
8
+ else
9
+ file = File.join(File.dirname(__FILE__), '..', '..', 'tmp', filename)
10
+ end
11
+ unless File.exist? file
12
+ puts 'downloading database'
13
+ url = 'http://ipgeobase.ru/files/db/Main/geo_files.tar.gz'
14
+ Kernel.system("curl #{url} | tar -xzOf - #{filename} | iconv -f cp1251 -t utf-8 > #{file}")
15
+ end
16
+ File.read(file)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+
3
+ require "ipgeobase/task"
4
+
5
+ namespace :ipgeobase do
6
+ desc "Update cities and regions. Downloads file if it's not present in tmp/cities.txt"
7
+ task :cities => :environment do
8
+ puts 'updating cities'
9
+ russia = Ipgeobase::Country.find_or_create_by(name: 'Россия', code: 'RU')
10
+ ukraine = Ipgeobase::Country.find_or_create_by(name: 'Украина', code: 'UA')
11
+ content = Ipgeobase::Task.obtain_content_by_filename('cities.txt')
12
+ content.each_line do |c|
13
+ options = c.split("\t")
14
+ country = if options[3].include? "Украина"
15
+ ukraine
16
+ else
17
+ russia
18
+ end
19
+ city = Ipgeobase::City.find_or_initialize_by(id: options[0])
20
+ city.assign_attributes(city: options[1], region: options[2], district: options[3], lat: options[4], lon: options[5], country: country)
21
+ city.save!
22
+ end
23
+ end
24
+
25
+ desc "Update geo ips. Downloads file if it's not present in tmp/cidr_optim.txt"
26
+ task :ips => :environment do
27
+ puts 'updating ips'
28
+ content = Ipgeobase::Task.obtain_content_by_filename('cidr_optim.txt')
29
+ Ipgeobase::Ip.delete_all
30
+ content.each_line do |c|
31
+ options = c.split("\t")
32
+ next if options.last.to_i.zero?
33
+ city = Ipgeobase::City.where(id: options.last.strip.to_i).first
34
+ if city.nil?
35
+ p "No city"
36
+ p options
37
+ next
38
+ end
39
+ Ipgeobase::Ip.create(:start_ip => options.first.to_i, :end_ip => options.second.to_i, city_id: city.id)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module Ipgeobase
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glebtv_ipgeobase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - glebtv
8
+ - Avramov Vsevolod
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-05-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description:
43
+ email:
44
+ - glebtv@gmail.com
45
+ - gsevka@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - README.rdoc
53
+ - Rakefile
54
+ - app/models/ipgeobase/city.rb
55
+ - app/models/ipgeobase/country.rb
56
+ - app/models/ipgeobase/ip.rb
57
+ - glebtv_ipgeobase.gemspec
58
+ - lib/generators/ipgeobase/migration_generator.rb
59
+ - lib/generators/ipgeobase/templates/migration.rb
60
+ - lib/glebtv_ipgeobase.rb
61
+ - lib/ipgeobase.rb
62
+ - lib/ipgeobase/belongs_to_region.rb
63
+ - lib/ipgeobase/engine.rb
64
+ - lib/ipgeobase/task.rb
65
+ - lib/ipgeobase/tasks.rake
66
+ - lib/ipgeobase/version.rb
67
+ homepage: http://github.com/glebtv/ipgeobase
68
+ licenses: []
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.0.0
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.4.5
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: upload archive from IPGeoBase.ru to your project
90
+ test_files: []