| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 | 
							- # @Author    : Rocky
 
- # @File      : IPWeatherObject.py
 
- # @Time      : 2023/8/16 8:56
 
- import datetime
 
- import geoip2.webservice
 
- import requests
 
- from Model.models import IPAddr, OpenWeatherMapCallCount
 
- from Object.AWS.S3Email import S3Email
 
- from Object.RedisObject import RedisObject
 
- from Service.CommonService import CommonService
 
- from Ansjer.config import LOGGER, CONFIG_INFO
 
- class IPQuery:
 
-     """
 
-     阿里云IP地址查询
 
-     https://market.aliyun.com/products/57002003/cmapi021970.html?spm=5176.2020520132.recommend-card.dbottom-suggestion.33e17218GYjWDt#sku=yuncode15970000020
 
-     """
 
-     def __init__(self, ip):
 
-         self.appcode = 'd7d63b34b1d54214be446608a57ff0a2'
 
-         self.host = 'https://c2ba.api.huachen.cn'
 
-         self.path = '/ip'
 
-         self.district = ''  # 区
 
-         self.city = ''  # 市
 
-         self.region = ''  # 省/州
 
-         self.country_id = ''
 
-         param = 'ip=' + ip
 
-         url = self.host + self.path + '?' + param
 
-         # 获取ip的区级和城市信息
 
-         headers = {'Authorization': 'APPCODE ' + self.appcode}
 
-         res = requests.get(url=url, headers=headers)
 
-         if res.status_code == 200:
 
-             # 反序列化响应数据
 
-             res_data = eval(res.content.decode('utf-8'))
 
-             if res_data['ret'] == 200:
 
-                 district = res_data['data']['district']
 
-                 city = res_data['data']['city']
 
-                 region = res_data['data']['region']
 
-                 country_id = res_data['data']['country_id']
 
-                 # 国内城市数据不为空字符,拼上'市'字
 
-                 if country_id == 'CN' and city != '':
 
-                     city += '市'
 
-                 # ip地址信息存表或更新
 
-                 ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False)
 
-                 if ip_addr_qs.exists():
 
-                     ip_addr_qs.update(district=district, city=city, region=region, country_code=country_id)
 
-                 else:
 
-                     IPAddr.objects.create(ip=ip, district=district, city=city, region=region, country_code=country_id)
 
-                 self.city = city  # 市
 
-                 self.region = region  # 省/州
 
-                 if district != '':
 
-                     self.district = district
 
-                 elif city != '':
 
-                     self.district = city
 
-                 self.country_id = country_id
 
- class WeatherInfo:
 
-     """
 
-     阿里云墨迹天气服务
 
-     https://market.aliyun.com/products/57096001/cmapi013828.html?spm=5176.2020520132.101.19.2b8f7218NuiGPd#sku=yuncode782800000
 
-     """
 
-     def __init__(self, city_id):
 
-         self.appcode = 'd7d63b34b1d54214be446608a57ff0a2'
 
-         self.headers = {'Authorization': 'APPCODE ' + self.appcode,
 
-                         'Content-Type': 'application/x-www-form-urlencoded'}
 
-         self.city_id = city_id
 
-     def get_city_weather(self):
 
-         url = "https://aliv18.data.moji.com/whapi/json/alicityweather/condition"  # 获取实时天气
 
-         data = {'cityId': self.city_id}
 
-         response = requests.post(url, headers=self.headers, data=data, verify=False)
 
-         if response.status_code == 200:
 
-             result = response.json()
 
-             if result['code'] == 0:
 
-                 # 返回温湿度
 
-                 return result['data']['condition']['temp'], result['data']['condition']['humidity']
 
-         return None, None
 
-     def get_city_24_weather(self):
 
-         url = 'https://aliv18.data.moji.com/whapi/json/alicityweather/forecast24hours'  # 获取城市24小时天气
 
-         data = {'cityId': self.city_id}
 
-         response = requests.post(url, headers=self.headers, data=data, verify=False)
 
-         if response.status_code == 200:
 
-             result = response.json()
 
-             if result['code'] == 0:
 
-                 # 返回天气列表
 
-                 return result['data']['hourly']
 
-         return None
 
- class GeoIP2:
 
-     """
 
-     MaxMind GeoIP2查询国外ip
 
-     同时保存ip信息
 
-     https://www.maxmind.com/
 
-     """
 
-     def __init__(self, ip):
 
-         self.account_id = 938644
 
-         self.license_key = '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'
 
-         self.license_key_sandbox = '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'
 
-         try:
 
-             with geoip2.webservice.Client(self.account_id, self.license_key) as client:
 
-                 # You can also use `client.city` or `client.insights`
 
-                 # `client.insights` is not available to GeoLite2 users
 
-                 response = client.city(ip)
 
-                 # 经纬度精确到小数点两位
 
-                 lat = round(response.location.latitude, 2)
 
-                 lon = round(response.location.longitude, 2)
 
-                 # 获取中文或英文城市名,省/州
 
-                 city = ''
 
-                 city_names = response.city.names
 
-                 city_cn = city_names.get('zh-CN')
 
-                 if city_cn:
 
-                     city = city_cn
 
-                 elif city_names.get('en'):
 
-                     city = city_names['en']
 
-                 region = ''
 
-                 subdivisions_names = response.subdivisions[0].names
 
-                 region_cn = subdivisions_names.get('zh-CN')
 
-                 if region_cn:
 
-                     region = region_cn
 
-                 elif subdivisions_names.get('en'):
 
-                     region = subdivisions_names['en']
 
-                 country_code = response.country.iso_code
 
-                 # 保存ip信息
 
-                 ip_addr_data = {
 
-                     'ip': ip,
 
-                     'lat': lat,
 
-                     'lon': lon,
 
-                     'city': city,
 
-                     'region': region,
 
-                     'country_code': country_code,
 
-                     'is_geoip2': True
 
-                 }
 
-                 IPAddr.objects.create(**ip_addr_data)
 
-         except Exception as e:
 
-             LOGGER.info('GeoIP2解析ip异常:error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
- class OpenWeatherMap:
 
-     """
 
-     OpenWeatherMap查询国外天气服务
 
-     https://openweathermap.org/
 
-     """
 
-     def __init__(self, lat, lon):
 
-         self.appid = '7a6cd7dfeb034ededa451ed575788857'
 
-         self.lat = lat  # 纬度
 
-         self.lon = lon  # 经度
 
-     def get_weather(self):
 
-         """
 
-         从缓存查询天气数据
 
-         或者查询当前天气,并缓存数据
 
-         @return: temp, humidity
 
-         """
 
-         # 查询缓存数据
 
-         today = datetime.datetime.today()
 
-         now_time = datetime.datetime(today.year, today.month, today.day, today.hour)
 
-         str_time = now_time.strftime('%Y-%m-%d %H:%M:%S')
 
-         time_stamp = CommonService.str_to_timestamp(str_time)
 
-         key = 'weather:lat:{}_lon:{}_time_stamp:{}'.format(self.lat, self.lon, time_stamp)
 
-         redis_obj = RedisObject()
 
-         weather = redis_obj.get_data(key)
 
-         if weather:
 
-             temp, humidity = weather.split('/')
 
-         else:
 
-             temp, humidity = self.get_current_weather(str_time[:7])
 
-             if temp is not None and humidity is not None:
 
-                 key = 'weather:lat:{}_lon:{}_time_stamp:{}'.format(self.lat, self.lon, time_stamp)
 
-                 redis_obj.set_ex_data(key, '{}/{}'.format(temp, humidity), 3600)
 
-         return temp, humidity
 
-     def get_current_weather(self, month):
 
-         """
 
-         根据经纬度获取当前天气
 
-         @param month: 年月份
 
-         @return: temp, humidity
 
-         """
 
-         url = 'https://api.openweathermap.org/data/2.5/weather'
 
-         params = {
 
-             'lat': self.lat,
 
-             'lon': self.lon,
 
-             'appid': self.appid,
 
-             'units': 'metric'   # 公制单位,温度单位:摄氏度
 
-         }
 
-         res = requests.get(url=url, params=params, timeout=10)
 
-         # 记录调用次数
 
-         open_weather_map_call_count_qs = OpenWeatherMapCallCount.objects.filter(month=month).values('count')
 
-         if not open_weather_map_call_count_qs.exists():
 
-             OpenWeatherMapCallCount.objects.create(month=month)
 
-         else:
 
-             count = open_weather_map_call_count_qs[0]['count'] + 1
 
-             open_weather_map_call_count_qs.update(count=count)
 
-             # 调用次数超过750,000,邮件提醒
 
-             warning_count = 750000
 
-             if count > warning_count:
 
-                 redis_obj = RedisObject()
 
-                 key = 'open_weather_map_call_count_warning_time_limit'
 
-                 time_limit = redis_obj.get_data(key)
 
-                 if not time_limit:
 
-                     # 限制一天提醒一次
 
-                     redis_obj.set_data(key, 1, 60 * 60 * 24)
 
-                     subject = '邮件提醒'
 
-                     data = '{}服open weather调用次数大于{}'.format(CONFIG_INFO, warning_count)
 
-                     S3Email().send_email(subject, data, 'servers@ansjer.com')
 
-         if res.status_code != 200:
 
-             return None, None
 
-         res_data = eval(res.text)
 
-         if res_data['cod'] != 200:
 
-             return None, None
 
-         temp = str(int(res_data['main']['temp']))
 
-         humidity = str(int(res_data['main']['humidity']))
 
-         return temp, humidity
 
 
  |