Пример #1
0
def send_email(sender: str, recipient: str, subject: str,
               body_text: str) -> bool:
    charset = "UTF-8"
    client = boto3.client('ses', region_name=CONFIG.get('aws-region'))
    try:
        response = client.send_email(Destination={
            'ToAddresses': [recipient],
        },
                                     Message={
                                         'Body': {
                                             'Text': {
                                                 'Charset': charset,
                                                 'Data': body_text
                                             },
                                         },
                                         'Subject': {
                                             'Charset': charset,
                                             'Data': subject
                                         },
                                     },
                                     Source=sender)
    except ClientError as e:
        logger.error(e.response['Error']['Message'])
        return False
    else:
        logger.debug("Email sent! Message ID : {}".format(
            response['MessageId']))
        return True
Пример #2
0
def fetch_usa_rt_estimate(fips: str) -> RtEstimate:
    rdb: RDBManager = RDBManager(reader=True)
    rt_estimates_data, err = rdb.execute(sql_query="""
			SELECT
				`date`,
				`rt_estimate`,
				`rt_low`,
				`rt_high`
			FROM `rt_estimates`
			WHERE
				`country_code` = 'USA'
				AND
				`region_code` = '{}'
			ORDER BY `date` ASC
		""".format(fips))
    if err is not None:
        logger.error(err)
    if len(rt_estimates_data) > 0:
        rt_estimate = RtEstimate(
            _date=[item['date'] for item in rt_estimates_data],
            rt_estimate=[
                float(item['rt_estimate']) for item in rt_estimates_data
            ],
            rt_low=[float(item['rt_low']) for item in rt_estimates_data],
            rt_high=[float(item['rt_high']) for item in rt_estimates_data])
        return rt_estimate
    return RtEstimate()
Пример #3
0
	def unsubscribed(self) -> bool:
		unsub_status = False
		try:
			unsub_status = bool(self.get_human_attribute(attribute_name=HumanProperties.UNSUBSCRIBED.value))
		except Exception as e:
			logger.error(e)
		return unsub_status
Пример #4
0
	def get_most_recent_location(self) -> (float, float):
		rdb = RDBManager(True)
		err = None
		try:
			most_recent_location, err = rdb.execute(
				sql_query="""
					SELECT 
						`latitude` AS `{}`, 
						`longitude` AS `{}`
					FROM `geolocations`
					WHERE 
						`human_id` = {}
						AND
						`latitude` IS NOT NULL
						AND
						`longitude` IS NOT NULL
					ORDER BY `created` DESC
					LIMIT 1
				""".format(
					CoordinateType.LATITUDE.value,
					CoordinateType.LONGITUDE.value,
					mysql_db_format_value(value=self.id)
				)
			)
		except Exception as e:
			logger.error(e)

		if len(most_recent_location) == 1:
			return float(most_recent_location[0][CoordinateType.LATITUDE.value]), \
				   float(most_recent_location[0][CoordinateType.LONGITUDE.value])
		else:
			return None, None
Пример #5
0
def get_all_humans_for_telegram_notifications(hours_of_day: list) -> list:
	if not isinstance(hours_of_day, list) or len(hours_of_day) == 0:
		return []

	for hour_of_day in hours_of_day:
		if not isinstance(hour_of_day, int) or (hour_of_day < 0 or hour_of_day > 23):
			return []

	hours_of_day = list(set(hours_of_day))

	rdb = RDBManager(True)
	audience = []
	try:
		audience, err = rdb.execute(
			sql_query="""
				SELECT 
					`id`, 
					`telegram_human_id`
				FROM `humans`
				WHERE
					HOUR(CONVERT_TZ(UTC_TIMESTAMP(),'UTC',`current_tz`)) IN ({})
					AND 
					`telegram_human_id` is not null
					AND 
					`unsubscribed` = 0
			""".format(
				", ".join([str(hour_of_day) for hour_of_day in hours_of_day])
			)
		)
	except Exception as e:
		logger.error(e)
	return audience
Пример #6
0
def verify_telegram_id_exists(telegram_human_id: int) -> (bool, str):
	if not isinstance(telegram_human_id, int):
		return TypeError('`telegram_human_id` of type {}. Expected [int]'.format(type(telegram_human_id)))

	rdb = RDBManager(True)
	err = None
	try:
		telegram_human_id_search_results, err = rdb.execute(
			sql_query="""
						SELECT `{}`
						FROM `humans`
						WHERE `{}` = {}
					""".format(
				HumanProperties.ID.value,
				HumanProperties.TELEGRAM_HUMAN_ID.value,
				telegram_human_id
			)
		)
	except Exception as e:
		logger.error(e)

	if len(telegram_human_id_search_results) == 1:
		return True, telegram_human_id_search_results[0][HumanProperties.ID.value]
	else:
		return False, None
def clean_data(data: pd.DataFrame) -> pd.DataFrame:
    logger.debug("Cleaning dataset...")
    data: pd.DataFrame = data[~pd.isna(data['ID'])]
    data: pd.DataFrame = data[~pd.isna(data['date_confirmation'])]
    data['date_confirmation'] = pd.to_datetime(
        data['date_confirmation'].apply(lambda x: x[:10]))
    data['created'] = data['date_confirmation']
    data['modified'] = data['date_confirmation']
    data['latitude'] = pd.to_numeric(data['latitude'])
    data['longitude'] = pd.to_numeric(data['longitude'])
    data['biological_sex'] = data['sex'].apply(
        lambda x: 'F' if x == 'female' else ('M' if x == 'male' else np.nan))
    data['symptom'] = 'verified_covid19'
    data['source'] = 'beoutbreakprepared'
    data['source_id'] = data['ID']
    data['id'] = data['source_id'].apply(lambda x: str(uuid.uuid4()))
    data['human_id'] = data['id']
    try:
        source_ids_to_remove = get_existing_source_ids()
    except Exception as e:
        logger.error(e)
    else:
        data: pd.DataFrame = data[~data['source_id'].isin(source_ids_to_remove
                                                          )]
    return data
Пример #8
0
	def update_tz(self, lat: float, lng: float) -> bool:
		rdb = RDBManager()
		err = None
		try:
			_, err = rdb.execute(
				sql_query="""
					UPDATE `humans`
					SET
						`current_tz` = (
							SELECT `timezone_name`
							FROM `timezones`
							WHERE mbrcontains(area, point({}, {})) 
							LIMIT 1
						)
					WHERE
						`id` = {}
						""".format(
					mysql_db_format_value(value=lng),
					mysql_db_format_value(value=lat),
					mysql_db_format_value(value=self.id)
				)
			)
		except Exception as e:
			logger.error(e)

		return err is None
Пример #9
0
	def log_location(self, latitude: float, longitude: float, send_alert: bool = True) -> bool:
		if not isinstance(latitude, float) or not isinstance(longitude, float):
			return False

		rdb = RDBManager()
		err = None
		try:
			_, err = rdb.execute(
				sql_query="""
					INSERT IGNORE 
					INTO `geolocations`(
						`human_id`, `created`, `modified`, `latitude`, `longitude`, `latitude_noise`, `longitude_noise`
					)
					VALUES ({}, UTC_TIMESTAMP(), UTC_TIMESTAMP(), {}, {}, ROUND(gauss(0,0.001), 10), ROUND(gauss(0,0.001), 10))
				""".format(
					mysql_db_format_value(value=self.id),
					mysql_db_format_value(value=round(latitude, 10)),
					mysql_db_format_value(value=round(longitude, 10))
				)
			)
		except Exception as e:
			logger.error(e)

		if send_alert:
			self.send_proximity_alert(lat=latitude, lng=longitude)

		self.update_tz(lat=latitude, lng=longitude)

		return err is None
Пример #10
0
    def return_response(cls, data={}, status=200, message="", headers={},
                        error_code=200):
        try:
            logger.debug('Return status %s %s', status, message)
        except:
            app.logger.error(traceback.format_exc())

        try:
            filters = request.args.get('filters')
            if filters:
                fd = BaseDict(data).filter(*filters.split(','))
                data = fd
        except:
            app.logger.error(traceback.format_exc())
            data = data

        try:
            if isinstance(data, db.Model):
                data = data.format()
            elif isinstance(data, list) and data and \
                    isinstance(data[0], db.Model):
                data = [o.format() for o in data]

        except:
            logger.error(traceback.format_exc())
            data = data

        res = cls(
            data=data,
            status=status,
            message=message,
            error_code=error_code
        ).to_dict()

        return make_response(jsonify(res), status, headers)
Пример #11
0
def update_rt_estimates_usa():
    counties_full: DataFrame = get_us_county_data()
    all_fips: List[str] = counties_full.index.get_level_values(
        'fips').unique().to_list()
    all_estimates: List[DataFrame] = []
    for fips in all_fips:
        try:
            county_data = counties_full.xs(fips)
        except KeyError as ke:
            logger.error(ke)
        if len(county_data) <= 1:
            continue
        county_name = county_data.iloc[0]['county']
        state_name = county_data.iloc[0]['state']
        country_code = 'USA'
        cases = county_data['cases']
        _, smoothed, index_dates = prepare_cases(cases=cases)
        try:
            rt, low, high = compute_rt(smoothed_new_cases=smoothed)
        except TimeSeriesDimensionError as e:
            logger.error(e)
            continue
        rt_region_estimate = DataFrame({
            'rt_estimate': rt,
            'rt_low': low,
            'rt_high': high,
            'date': index_dates,
            'country_code': country_code,
            'first_administrative_division_name': state_name,
            'region_code': fips,
            'region_name': county_name
        })
        all_estimates.append(rt_region_estimate)

    all_estimates_df = pd.concat(all_estimates)
    all_estimates_df.reset_index(inplace=True, drop=True)
    database_connection = sqlalchemy.create_engine(generate_db_uri())
    all_estimates_tbl_name: str = 'rt_estimates'
    all_estimates_tmp_tbl_name: str = 'rt_estimates_tmp'
    all_estimates_df.to_sql(name=all_estimates_tmp_tbl_name,
                            con=database_connection,
                            if_exists='replace',
                            index=False)
    with database_connection.begin() as cnx:
        insert_sql: str = """
			INSERT IGNORE INTO {}({}, `modified`)
			SELECT {}, UTC_TIMESTAMP() FROM {} as t
			ON DUPLICATE KEY UPDATE
				`rt_estimate` = t.`rt_estimate`,
				`rt_low` = t.`rt_low`,
				`rt_high` = t.`rt_high`,
				`modified` = UTC_TIMESTAMP()
		""".format(all_estimates_tbl_name, ', '.join(list(all_estimates_df.columns)),
             ', '.join(list(all_estimates_df.columns)),
             all_estimates_tmp_tbl_name)
        cnx.execute(insert_sql)
        delete_tmp_table_sql: str = "DROP TABLE IF EXISTS {}".format(
            all_estimates_tmp_tbl_name)
        cnx.execute(delete_tmp_table_sql)
Пример #12
0
def get_weather(lat, lng, key='d122fe39de94bf2c6c2ea443e9fef496'):
    """
    获取天气预报
    DOC:https://darksky.net/dev/docs/forecast
    """

    #  key1 = 'd122fe39de94bf2c6c2ea443e9fef496'
    #  key2 = 'ca5680b002774a7cba5cad57df33c20e'
    #  keys = ['04a0ab1e89d625503ad4d53c31622b04',
    #  'd122fe39de94bf2c6c2ea443e9fef496',
    #  'ca5680b002774a7cba5cad57df33c20e']

    def _f2c(f):
        """华氏度转变成摄氏度"""
        return float('{:0.2f}'.format((float(f) - 32) / 1.8))

    def _format_hour(h):
        """格式化小时内天气"""
        h['temperature'] = _f2c(h['temperature'])
        h['apparentTemperature'] = _f2c(h['apparentTemperature'])
        h['dewPoint'] = _f2c(h['dewPoint'])
        return h

    def _format_day(d):
        """格式化每天天气"""
        d['temperatureMin'] = _f2c(d['temperatureMin'])
        d['temperatureMax'] = _f2c(d['temperatureMax'])
        d['apparentTemperatureMin'] = _f2c(d['apparentTemperatureMin'])
        d['apparentTemperatureMax'] = _f2c(d['apparentTemperatureMax'])
        d['dewPoint'] = _f2c(d['dewPoint'])
        return d

    def _format(d):
        """格式化天气"""
        d['scale'] = '°F'

        if d.get('timezone') and 'America' not in d.get('timezone'):
            d['currently'] = _format_hour(d['currently'])
            d['hourly']['data'] = [
                _format_hour(o) for o in d['hourly']['data']
            ]
            d['daily']['data'] = [_format_day(o) for o in d['daily']['data']]
            d['scale'] = '°C'

        return d

    try:
        url = 'https://api.darksky.net/forecast/{}/{},{}'
        res = requests.get(url.format(key, lat, lng))
        if res.status_code != 200:
            logger.error('weather error %s', res.content)
            #  res = requests.get(url.format(key2, lat, lng))
            #  if res.status_code != 200:
            #  logger.error('weather error %s', res.content)
        return _format(res.json())
    except Exception:
        logger.error(traceback.format_exc())
        return {}
Пример #13
0
 def run(self):
     addr = ("", self.port)
     try:                    
         adapter_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)          
         adapter_sock.bind(addr) 
         logger.info("IPv4 UDP服务器已经启动,服务器绑定地址%s" % str(addr))
     except Exception, e:
         logger.error("启动IPv4 UDP服务器失败,错误原因%s" % str(e))
         exit(0)
Пример #14
0
 def get(self, name):
     res = self.client.get(name)
     try:
         res = utils.unsequence(res)
         return res
     except:
         logger.error(res)
         logger.error(traceback.format_exc())
         return None
Пример #15
0
 def pre_execute(self, sql_query: str) -> Exception:
     err = None
     try:
         with self.connection.cursor() as cursor:
             cursor.execute(sql_query)
             self.connection.commit()
     except BaseException as e:
         logger.error(e)
         err = e
     return err
Пример #16
0
 def run(self):      
     addr = ("", self.port)
     try:            
         self.adapter_sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)           
         self.adapter_sock.bind(addr)
         self.adapter_sock.listen(10)
         logger.info("IPv6 TCP服务器已经启动,服务器绑定地址%s" % str(addr))  
     except Exception, e:
         logger.error("启动IPv6 TCP服务器失败,错误原因%s" % str(e))
         exit(0)
Пример #17
0
 def georadius(self, name, longitude, latitude, radius, unit='km',
               withdist=True, withcoord=False, withhash=False, count=11,
               sort='ASC', store=None, store_dist=None):
     try:
         kw = locals()
         kw.pop('self')
         return self.client.georadius(**kw)
     except Exception as e:
         logger.error(e)
         return []
Пример #18
0
def fulfill_help_request(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Click here to talk to us: @OpendemicTeam"
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Пример #19
0
def fulfill_report_telegram_command(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="See options below 👇",
            reply_markup=get_telegram_menu()
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Пример #20
0
def fulfill_invalid_telegram_command(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Oops... This command is not valid. Type `/` to see valid commands.",
            reply_markup=get_telegram_menu()
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Пример #21
0
 def get_exception_message(e, language):
     """
     Logs traceback message and get appropriate exception message from config file.
     :param exception e: exception to be handled
     :param str language: _language code
     :rtype: str
     :return: an exception message that will be delivered to the user
     """
     logger.warning("An exception occurred.")
     exception_type = convert_instance_type_to_str(type(e))
     message = EXCEPTION_MESSAGES.get(exception_type, "exception")[language]
     traceback_message = traceback.format_exc()
     logger.error(traceback_message)
     return message
Пример #22
0
def fulfill_log_symptom(human: Human, symptom_name: str) -> bool:
    bot = get_telegram_bot_instance()

    try:
        human.log_symptom(symptom_name=symptom_name)

        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Noted!"
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Пример #23
0
def location():
    # Fetch or create human, log its location, and return nearby risky humans
    params = create_parameters()
    validation_error_response = validate_location_url_params(params=params)
    if len(validation_error_response) > 0:
        return_invalid_response(validation_error_response)

    human = model.get_human_from_fingerprint(fingerprint=params[LocationResourceFields.FINGERPRINT.value])
    if human is None:
        human, err = model.create_human(fingerprint=params[LocationResourceFields.FINGERPRINT.value])
        if err is not None:
            logger.error(err)
            response = Response(
                response=json.dumps({
                    "error": "Error creating human with fingerprint {}".format(params[LocationResourceFields.FINGERPRINT.value])
                }),
                status=403,
                mimetype='application/json'
            )
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response

    human.log_location(
        latitude=float(params[LocationResourceFields.LATITUDE.value]),
        longitude=float(params[LocationResourceFields.LONGITUDE.value]),
        send_alert=False)

    self_lat_lng = [params[LocationResourceFields.LONGITUDE.value], params[LocationResourceFields.LATITUDE.value]]
    self_geojson_feature = {
        'type': "Point",
        'coordinates': self_lat_lng
    }

    risky_humans_geojson = model.get_risky_humans_geojson(
        lat=params[LocationResourceFields.LATITUDE.value],
        lng=params[LocationResourceFields.LONGITUDE.value],
        days_window=int(CONFIG.get('days_window')),
        km_radius=int(CONFIG.get('km_radius'))
    )

    return render_template(
        'map.html',
        self_geojson_feature=self_geojson_feature,
        self_lat_lng=self_lat_lng,
        risky_humans_geojson=risky_humans_geojson,
        km_radius=int(CONFIG.get('km_radius')),
        include_legend=params[LocationResourceFields.INCLUDE_LEGEND.value],
        zoom_level=9
    )
Пример #24
0
 def execute(self, sql_query: str) -> (list, Exception):
     err = None
     result = []
     starting_time = time()
     try:
         with self.connection.cursor() as cursor:
             cursor.execute(sql_query)
             result = cursor.fetchall()
             QUERY_DURATION.labels('opendemic', sql_query).observe(
                 round(time() - starting_time, 2))
             self.connection.commit()
     except BaseException as e:
         logger.error(e)
         err = e
     return result, err
Пример #25
0
def fulfill_my_map_request(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        bot.send_message(
            chat_id=human.telegram_human_id,
            text="See who's around you 👇",
            parse_mode='markdown',
            reply_markup=make_reply_keyboard_markup(markup_map=[
                {'text': "🌍 See Map", 'url': CONFIG.get('client-url')},
            ])
        )
    except Exception as e:
        logger.error(e)
        return False
    return True
Пример #26
0
	def get_human_attribute(self, attribute_name: str) -> str:
		rdb = RDBManager(True)
		try:
			human_id_search_results, err = rdb.execute(
				sql_query="""
					SELECT *
					FROM `humans`
					WHERE `id` = '{}'
				""".format(self._human_id)
			)
		except Exception as e:
			logger.error(e)

		if len(human_id_search_results) == 1:
			if attribute_name in human_id_search_results[0]:
				return human_id_search_results[0][attribute_name]
		return None
Пример #27
0
def create_parameters() -> dict:
    # Create parameters from a request
    params = dict()
    params[LocationResourceFields.FINGERPRINT.value] = request.args.get(LocationResourceFields.FINGERPRINT.value)
    params[LocationResourceFields.LATITUDE.value] = request.args.get(LocationResourceFields.LATITUDE.value)
    params[LocationResourceFields.LONGITUDE.value] = request.args.get(LocationResourceFields.LONGITUDE.value)
    params[LocationResourceFields.INCLUDE_LEGEND.value] = request.args.get(LocationResourceFields.INCLUDE_LEGEND.value)
    if params[LocationResourceFields.INCLUDE_LEGEND.value] is None:
        params[LocationResourceFields.INCLUDE_LEGEND.value] = True
    else:
        try:
            include_legend = bool(eval(str(params[LocationResourceFields.INCLUDE_LEGEND.value]).capitalize()))
        except NameError as e:
            logger.error(e)
            include_legend = True
        params[LocationResourceFields.INCLUDE_LEGEND.value] = include_legend
    return params
Пример #28
0
	def unsubscribe(self) -> bool:
		rdb = RDBManager()
		err = None
		try:
			_, err = rdb.execute(
				sql_query="""
					UPDATE `humans`
					SET
						`unsubscribed` = 1
					WHERE
						`id` = {}
						""".format(
					mysql_db_format_value(value=self.id)
				)
			)
		except Exception as e:
			logger.error(e)

		return err is None
Пример #29
0
def get_human_from_fingerprint(fingerprint: str) -> Human:
	rdb = RDBManager(True)
	err = None
	try:
		records, err = rdb.execute(
			sql_query="""
						SELECT `{}`
						FROM `humans`
						WHERE `{}` = {}
					""".format(
				HumanProperties.ID.value,
				HumanProperties.FINGERPRINT.value,
				mysql_db_format_value(fingerprint)
			)
		)
	except Exception as e:
		logger.error(e)

	return Human(human_id=records[0][HumanProperties.ID.value]) if len(records) == 1 else None
Пример #30
0
def init_request_data():
    g.request_start_time = time.time()
    g.api_id = int(g.request_start_time * 1000)
    if app.config['DEBUG']:
        try:
            data = request.data
            args = request.args or {}
            #  json_data = request.json or {}
            #  form_data = request.form or {}
            h_data = request.headers or {}

            logger.debug('{} Request Begin ID'.format('-' * 10))
            logger.debug('{} {}'.format(request.method, request.url))

            logger.debug('Header %s', dict(h_data))
            logger.debug('Data   %s', data)
        except Exception as e:
            logger.error('params %s', e)
            logger.error(traceback.format_exc())