def get_location(self): social_auth_user = UserSocialAuth.objects.get(user=self.user, provider='google-oauth2') oauth_data = social_auth_user.extra_data if 'expiration_date' not in oauth_data.keys(): oauth_data['expiration_date'] = 0 if oauth_data['expiration_date'] < time.mktime(datetime.datetime.now().timetuple()): oauth_data = refresh_access_token(oauth_data) try: latitude_data = get_latitude_location(oauth_data) except LatitudeNotOptedIn: self._save_location_status(UserLocationStatus.LOCATION_STATUS_NOT_OPTED_IN) logger.error('get_location failed for user %s because: Not opted in to Latitude' % self.user) return except LatitudeInvalidCredentials: self._save_location_status(UserLocationStatus.LOCATION_STATUS_INVALID_CREDENTIALS) logger.error('get_location failed for user %s because: Invalid Credentials' % self.user) return except LatitudeNoLocationHistory: self._save_location_status(UserLocationStatus.LOCATION_STATUS_NO_HISTORY) logger.error('get_location failed for user %s because: No history' % self.user) return except LatitudeUnknown: self._save_location_status(UserLocationStatus.LOCATION_STATUS_UNKNOWN) logger.error('get_location failed for user %s because: Unknown' % self.user) return self._save_location_status(UserLocationStatus.LOCATION_STATUS_OK) source_date = datetime.datetime.fromtimestamp(float(latitude_data['data']['timestampMs']) / 1000, GMT) location_source, created = LocationSource.objects.get_or_create(name='Google Latitude') geometry = json.dumps(dict( type='Point', coordinates=[ latitude_data['data']['longitude'], latitude_data['data']['latitude'] ] )) # The timestampMs member is the location unique id. If we already have this, let's just update the record user_location, created = UserLocation.objects.get_or_create(user=self.user, source_created=source_date, defaults={ 'geometry': geometry, 'source': location_source, 'source_data': latitude_data }) logger.info('%s UserLocation for %s.' % ('Created' if created else 'Update', self.user)) if not created: user_location.updated = d_now() user_location.save() social_auth_user.oauth_data = oauth_data social_auth_user.save()
def check_users_weather_alerts(): logger.info('Checking user weather alerts') now = d_now() current_weather_alerts = WeatherAlert.objects.filter(effective__lte=now, expires__gte=now) logger.info('Current active alert count: %s' % len(current_weather_alerts)) current_located_users = UserLocation.objects\ .filter(updated__gte=now - timedelta(minutes=USER_LOCATION_MAX_AGE))\ .distinct('user')\ .order_by('user', '-updated') logger.info('Current located user count: %s' % len(current_located_users)) new_user_weather_alerts = [] for current_located_user in current_located_users: weather_alert_type_exclusions = [ uwate.weather_alert_type.id for uwate in UserWeatherAlertTypeExclusion.objects.filter(user=current_located_user.user) ] for current_weather_alert in current_weather_alerts: for location_id, bbox in current_weather_alert.shapes(bbox=True): if bbox.contains(current_located_user.shape): """ The user is in at least the bounding box of a weather alert. Let's see if the actually polygon contains the user. """ if current_weather_alert.location_type.name == 'Polygon': weather_alert_shape = current_weather_alert.shapes()[0][1] else: if current_weather_alert.location_type.name == 'UGC': TheModel = UGC elif current_weather_alert.location_type.name == 'FIPS': TheModel = County elif current_weather_alert.location_type.name == 'Marine': TheModel = Marine weather_alert_shape = TheModel.objects.get(id=location_id).shape if weather_alert_shape.contains(current_located_user.shape): """ The user is in a weather alert polygon Let's see if we've already alerted them. """ user_weather_alert, created = UserWeatherAlert.objects.get_or_create( user=current_located_user.user, weather_alert=current_weather_alert, defaults={ 'user_location': current_located_user, 'weather_alert_location_id': location_id }) if created and current_weather_alert.weather_alert_type.id not in weather_alert_type_exclusions: new_user_weather_alerts.append(user_weather_alert) break """ Gathering of new user alerts complete, send emails and texts """ send_bulk_weather_alerts(new_user_weather_alerts)
def leaderboards_landing(request): user_timezone = get_timezone_for_user(request.user) now = d_now().astimezone(timezone(user_timezone)) leaderboard_month_date = leaderboards_start_date current_month_date = datetime.date(now.year, now.month, 1) past_leaderboard_months = [] while leaderboard_month_date < current_month_date: past_leaderboard_months.append(leaderboard_month_date) leaderboard_month_date = add_months(leaderboard_month_date, 1) context = { 'current_year': str(now.year), 'current_month': str(now.month).zfill(2), 'past_leaderboard_months': past_leaderboard_months, 'tab': 'leaderboards', } return render(request, 'leaderboards_landing.html', context)
def weather_alerts_state(request, state_code): """ GET /weather_alerts/state/<state_code>/ View list of weather alerts for a state """ state_code = state_code.upper() try: state = State.objects.get(code=state_code) except State.DoesNotExist: raise Http404 now = d_now() current_weather_alerts = WeatherAlert.objects.filter(effective__lte=now, expires__gte=now) current_weather_alerts_for_state = [] current_weather_alerts_json = {} current_weather_alerts_ids = [] for current_weather_alert in current_weather_alerts: for location_id in current_weather_alert.location_ids.split(' '): location_id_code = location_id[:2] if location_id_code == state_code and current_weather_alert.id not in current_weather_alerts_ids: current_weather_alerts_for_state.append(current_weather_alert) current_weather_alerts_json[current_weather_alert.id] = { 'geojson': current_weather_alert.geojson(), 'location_ids': current_weather_alert.location_ids, } current_weather_alerts_ids.append(current_weather_alert.id) return render( request, 'weather_alerts_state.html', { 'weather_alerts': current_weather_alerts_for_state, 'weather_alerts_json': json.dumps(current_weather_alerts_json), 'state': { 'code': state.code, 'name': state.name }, 'leaflet': True })
def weather_alerts_marine(request, zone_slug): """ GET /weather_alerts/marine/<zone_slug>/ View list of weather alerts for a marine zone """ try: marine_zone = MarineZone.objects.get(slug=zone_slug) except MarineZone.DoesNotExist: raise Http404 now = d_now() marine_zone_codes = marine_zone.codes.split(' ') current_weather_alerts = WeatherAlert.objects.filter(effective__lte=now, expires__gte=now) current_weather_alerts_for_marine_zone = [] current_weather_alerts_json = {} current_weather_alerts_ids = [] for current_weather_alert in current_weather_alerts: for location_id in current_weather_alert.location_ids.split(' '): location_id_code = location_id[:2] if location_id_code in marine_zone_codes and current_weather_alert.id not in current_weather_alerts_ids: current_weather_alerts_for_marine_zone.append(current_weather_alert) current_weather_alerts_json[current_weather_alert.id] = { 'geojson': current_weather_alert.geojson(), 'location_ids': current_weather_alert.location_ids, } current_weather_alerts_ids.append(current_weather_alert.id) return render( request, 'weather_alerts_marine.html', { 'weather_alerts': current_weather_alerts_for_marine_zone, 'weather_alerts_json': json.dumps(current_weather_alerts_json), 'marine_zone': marine_zone, 'leaflet': True })
def create_fake_weather_alert(user_id): user = User.objects.get(id=user_id) last_location = UserLocation.objects.filter(user=user).order_by('-created')[0] logger.info('Creating a fake alert near %s, %s.' % (last_location.geojson()['geometry']['coordinates'][0], last_location.geojson()['geometry']['coordinates'][1])) for ugc in UGC.objects.all(): if ugc.shape.contains(last_location.shape): now = d_now() fake_weather_alert = WeatherAlert( nws_id=''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6)), source_created=now, source_updated=now, effective=now - timedelta(minutes=10), expires=now + timedelta(hours=2), event='Winter Weather Advisory', title='Winter Weather Advisory issued November 26 at 4:17AM AKST until November 26 at 12:00PM AKST by NWS', summary='...WINTER WEATHER ADVISORY REMAINS IN EFFECT UNTIL NOON AKST TODAY... A WINTER WEATHER ADVISORY REMAINS IN EFFECT UNTIL NOON AKST TODAY. * SNOW...ADDITIONAL ACCUMULATIONS OF 1 TO 3 INCHES THROUGH NOON MONDAY. STORM TOTAL ACCUMULATION OF 5 TO 8 INCHES SINCE SUNDAY', url='http://wxwarn.me', ugc=ugc.id, location_type=LocationType.objects.get(name='UGC'), location_ids=ugc.id, fake=True) fake_weather_alert.save() break check_users_weather_alerts()
def _save_location_status(self, location_status): user_location_status, created = UserLocationStatus.objects.get_or_create(user=self.user, defaults={'location_status': location_status}) if not created: user_location_status.updated = d_now() user_location_status.location_status = location_status user_location_status.save()
def last_locations(self, minutes=60*24): # Get the last n minutes worth of locations for a user now = d_now() user_locations = UserLocation.objects.filter(user=self.user, updated__gt=now - datetime.timedelta(minutes=minutes)).order_by('-updated') return user_locations
def active(self): now = d_now() return self.effective <= now <= self.expires