mango_china_city 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8a9aee32f3a13c56565ddb4b5feac7338c30c6f28d29095b92770dfb1d21316c
4
+ data.tar.gz: 4640404eede191107fe4ad8940d6f16a915f3966b3543aa85cfb857f2b48fb12
5
+ SHA512:
6
+ metadata.gz: c5765e2247e3a0352a934f33adec28c9ae039be6ee25cbef4332014a8b58074bce480178e7fa29f9f82392400650285efe6691ace4c33aecbfaccc0febc0f24a
7
+ data.tar.gz: ea24d4f1063f4796b84673241576fbd7250702e0873b408dd6ab60e430fb6d47ba020ba460afdf2cd47a1b810bb302a7e2967d4612c8f8e94813df414dae611b
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://gems.ruby-china.com"
4
+
5
+ # Specify your gem's dependencies in mango_china_city.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem 'rest-client', '2.1.0'
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # MangoChinaCity
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mango_china_city`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'mango_china_city'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install mango_china_city
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mango_china_city.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "mango_china_city"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,18 @@
1
+ require 'rails/generators'
2
+
3
+ module MangoChinaCity
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def generate_migrates
9
+ copy_file "model/province.rb", "#{Rails.root}/app/models/province.rb"
10
+ copy_file "model/city.rb", "#{Rails.root}/app/models/city.rb"
11
+ copy_file "model/district.rb", "#{Rails.root}/app/models/district.rb"
12
+ copy_file "create_provinces.rb", "#{Rails.root}/db/migrate/#{Time.now.strftime("%Y%m%d%H%m")}01_create_provinces.rb"
13
+ copy_file "create_cities.rb", "#{Rails.root}/db/migrate/#{Time.now.strftime("%Y%m%d%H%m")}02_create_cities.rb"
14
+ copy_file "create_districts.rb", "#{Rails.root}/db/migrate/#{Time.now.strftime("%Y%m%d%H%m")}03_create_districts.rb"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ class CreateCities < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :cities do |t|
4
+ t.references :province
5
+ t.string :name, index: true, comment: '省名字'
6
+ t.string :code, index: true, comment: '省Code'
7
+ t.datetime :deleted_at
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class CreateDistricts < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :districts do |t|
4
+ t.references :province
5
+ t.references :city
6
+ t.string :name, index: true, comment: '省名字'
7
+ t.string :code, index: true, comment: '省Code'
8
+ t.datetime :deleted_at
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ class CreateProvinces < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :provinces do |t|
4
+ t.string :name, index: true, comment: '省名字'
5
+ t.string :code, index: true, comment: '省Code'
6
+ t.datetime :deleted_at
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ class City < ApplicationRecord
2
+ belongs_to :province
3
+ has_many :districts
4
+ end
@@ -0,0 +1,4 @@
1
+ class District < ApplicationRecord
2
+ belongs_to :province
3
+ belongs_to :city
4
+ end
@@ -0,0 +1,4 @@
1
+ class Province < ApplicationRecord
2
+ has_many :cities
3
+ has_many :districts
4
+ end
@@ -0,0 +1,13 @@
1
+ module MangoChinaCity
2
+ module Configure
3
+
4
+ attr_accessor :redis
5
+
6
+ def configure(*options)
7
+ yield self if block_given?
8
+ end
9
+
10
+ end
11
+ end
12
+
13
+
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MangoChinaCity
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "mango_china_city/version"
4
+ require_relative "mango_china_city/configure"
5
+
6
+ module MangoChinaCity
7
+
8
+ class << self
9
+ include Configure
10
+
11
+ # 国家统计局同步数据
12
+ def sync_data(gen_file=false)
13
+ json = { province: [] }
14
+ base_url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/"
15
+
16
+ province_res = convert_utf8( RestClient.get("#{base_url}index.html").body )
17
+ province_res.match(/<td>.+<\/td>/).to_s.gsub(/<br\/>|<\/td>|<td>/,'').split("</a>").each do |province|
18
+ # p_url省详情的页面地址, code 省code
19
+ p_url, code = province.match(/(\d+).html/).to_a
20
+ province_ = { name: province.match(/[\u4e00-\u9fa5]+/).to_s, code: "#{code}", city: []}
21
+ puts "正在同步#{province.match(/[\u4e00-\u9fa5]+/).to_s}"
22
+ # 获取省下的市
23
+ city_res = convert_utf8( RestClient.get("#{base_url}#{p_url}").body )
24
+
25
+ city_res.gsub(/\r|\n/,'').match(/<a href=.+<\/a>/).to_s.split("</tr>").each do |city|
26
+ c_url, c_code = city.match(/(\d+).html/).to_a
27
+ city_ = { name: city.match(/[\u4e00-\u9fa5]+/).to_s, code: "#{c_code}", district: [] }
28
+ puts "正在同步#{province.match(/[\u4e00-\u9fa5]+/).to_s}::#{city.match(/[\u4e00-\u9fa5]+/).to_s}"
29
+ # 获取市下的区
30
+ district_res = convert_utf8( RestClient.get("#{base_url}#{code}/#{c_url}").body )
31
+ district_res.gsub(/\r|\n/,'').match(/<a href=.+<\/a>/).to_s.split("</tr>").each do |district|
32
+ d_url, d_code = district.match(/(\d+).html/).to_a
33
+ city_[:district] << { name: district.match(/[\u4e00-\u9fa5]+/).to_s, code: d_code }
34
+ puts "正在同步#{province.match(/[\u4e00-\u9fa5]+/).to_s}::#{city.match(/[\u4e00-\u9fa5]+/).to_s}::#{district.match(/[\u4e00-\u9fa5]+/).to_s}"
35
+ end
36
+ province_[:city] << city_
37
+ end
38
+
39
+ json[:province] << province_
40
+ end
41
+
42
+ # 生成文件
43
+ File.open("#{Rails.root}/db/areas.json", 'w+') do |f|
44
+ f.write(json.to_json)
45
+ end if gen_file
46
+ puts '生在写入数据库...'
47
+ import_data(json)
48
+ puts '写入完成,同步数据结束!'
49
+ end
50
+
51
+ # 省市区信息写入数据库
52
+ def import_data(json)
53
+ data_province = Province.all.to_a
54
+ data_city = City.all.to_a
55
+ data_district = District.all.to_a
56
+
57
+ Province.transaction do
58
+ json[:province].each do |province|
59
+ province_ = Province.find_or_create_by(name: province[:name], code: province[:code])
60
+ data_province.delete_if{|e| e.code == province_.code}
61
+
62
+ province[:city].each do |city|
63
+ city_ = City.find_or_create_by(province: province_, name: city[:name], code: city[:code])
64
+ data_city.delete_if{|e| e.code == city_.code }
65
+
66
+ city[:district].each do |district|
67
+ district_ = District.find_or_create_by(province: province_, city: city_, name: district[:name], code: district[:code])
68
+ data_district.delete_if{|e| e.code == district_.code }
69
+ end
70
+ end
71
+ end
72
+
73
+ # 软删除更新地区
74
+ [data_province, data_city, data_district].flatten.each{|e| e.destroy}
75
+
76
+ # 重建缓存
77
+ build_cache if redis.present?
78
+ end
79
+ end
80
+
81
+ # 获取省市区
82
+ def list(code = nil)
83
+ code = code.to_s if code.present?
84
+ if redis.present? && redis.keys.include?("province_cache")
85
+ return JSON.parse( redis.get("province_cache") ) if code.nil?
86
+ return JSON.parse( redis.get("city_cache") )[code] if code.size == 2
87
+ return JSON.parse( redis.get("district_cache") )[code] if code.size != 2
88
+ else # 数据库查询
89
+ return Province.all.map{|e| {name: e.name, code: e.code}} if code.nil?
90
+ return City.where(province: Province.find_by(code: code)).map{|e| { name: e.name, code: e.code } } if code.size == 2
91
+ return District.where(city: City.find_by(code: code)).map{|e| { name: e.name, code: e.code }} if code.size != 2
92
+ end
93
+ end
94
+
95
+ def get(code)
96
+ code = code.to_s
97
+ result = nil
98
+ if redis.present? && redis.keys.include?("province_cache")
99
+ result = (JSON.parse( redis.get("province_cache") ).find{|e| e["code"] == code}["name"] rescue nil)
100
+ result = (JSON.parse( redis.get("city_cache") ).values.flatten.find{|e| e["code"] == code}["name"] rescue nil) if result.nil?
101
+ result = (JSON.parse( redis.get("district_cache") ).values.flatten.find{|e| e["code"] == code}["name"] rescue nil ) if result.nil?
102
+ else
103
+ result = Province.find_by(code: code).try(:name)
104
+ result = City.find_by(code: code).try(:name) if result.nil?
105
+ result = District.find_by(code: code).try(:name) if result.nil?
106
+ end
107
+
108
+ return result.to_s
109
+ end
110
+
111
+ # 获取数据库地区并缓存到redis
112
+ def build_cache
113
+ provinces_ = Province.not_deleted.to_a
114
+ cities_ = City.not_deleted.to_a
115
+ districts_ = District.not_deleted.to_a
116
+
117
+ cities = {}
118
+ districts = {}
119
+ redis.set("province_cache", provinces_.map{|e| { name: e.name, code: e.code }}.to_json)
120
+
121
+ provinces_.each do |province|
122
+ puts "正在缓存\e[0;32;49m<#{province.name}>\e[0m所有数据..."
123
+ cities.merge!( { province.code => cities_.select{|e| e.province_id == province.id}.map{|e| { name: e.name, code: e.code }} } )
124
+
125
+ cities_.each do |city|
126
+ districts.merge!( { city.code => districts_.select{|e| e.city_id == city.id }.map{|e| { name: e.name, code: e.code }} } )
127
+ end
128
+ puts "缓存\e[0;32;49m<#{province.name}>\e[0m完成!\n\n"
129
+ end
130
+ redis.set("city_cache", cities.to_json)
131
+ redis.set("district_cache", districts.to_json)
132
+ end
133
+
134
+ private
135
+ # 编码格式转换
136
+ def convert_utf8(str)
137
+ str.force_encoding('GB18030').encode('utf-8')
138
+ end
139
+
140
+ end
141
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mango_china_city
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - 刘琦
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-12-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.1.0
27
+ description: 包含数据迁移、数据同步。
28
+ email:
29
+ - l_qi199@163.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - bin/console
38
+ - bin/setup
39
+ - lib/generators/mango_china_city/install_generator.rb
40
+ - lib/generators/mango_china_city/templates/create_cities.rb
41
+ - lib/generators/mango_china_city/templates/create_districts.rb
42
+ - lib/generators/mango_china_city/templates/create_provinces.rb
43
+ - lib/generators/mango_china_city/templates/model/city.rb
44
+ - lib/generators/mango_china_city/templates/model/district.rb
45
+ - lib/generators/mango_china_city/templates/model/province.rb
46
+ - lib/mango_china_city.rb
47
+ - lib/mango_china_city/configure.rb
48
+ - lib/mango_china_city/version.rb
49
+ homepage: https://gitee.com/timision/mango_china_city.git
50
+ licenses: []
51
+ metadata:
52
+ homepage_uri: https://gitee.com/timision/mango_china_city.git
53
+ source_code_uri: https://gitee.com/timision/mango_china_city.git
54
+ changelog_uri: https://gitee.com/timision/mango_china_city.git
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.6.0
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.2.3
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: 省、市、区三级数据
74
+ test_files: []