Пример #1
0
def save_new_position(position, animal, request):
    if animal.active:
        if get_animal_position_by_date(animal.id, position.date) == None:
            position.animal_id = animal.id
            position.save()
            if (not position.charging and animal.positions[0] == position and
                animal.positions[0].outside() and ((animal.n_positions > 1 and not
                animal.positions[1].outside()) or animal.n_positions == 1)):
                parameters = {'name': animal.user.name,
                 'animal_name': animal.name if (animal.name != None and
                                animal.name != '') else animal.imei,
                 'fancy_date': get_fancy_time_from_utc(position.date,
                                locale=animal.user.locale),
                 'fancy_date_eval': escape_code_to_eval(
                    "get_fancy_time_from_utc(internal_parse_datetime('"
                    + internal_format_datetime(position.date)
                    + "'), request=request)"),
                 'date': format_utcdatetime(position.date,
                    locale=animal.user.locale)
                 }
                ondestan.services.\
                notification_service.process_notification(
                    'outside_plots', animal.user.email, True, 3,
                    True, True, parameters)
            if position.date != None:
                if not compare_datetime_ago_from_utc(position.date,
                    relativedelta(hours=+no_positions_max_hours)):
                    animal.checks_wo_pos = 0
                    animal.update()
    process_position_general_notifications(position, animal, request)
Пример #2
0
def json_animal_approx_position(request):
    geojson = []
    animal_id = request.matchdict['animal_id']
    is_admin = check_permission('admin', request)
    email = get_user_email(request)
    animal = None
    if animal_id != None:
        try:
            animal = animal_service.get_animal_by_id(int(animal_id))
        except ValueError:
            pass
    if animal != None and (is_admin or animal.user.email == email):
        instant = datetime.utcnow()
        position = animal.get_approx_position_as_geojson(instant)
        if position != None:
            parameters = {
                'animal_name': animal.name,
                'name': animal.user.email,
                'imei': animal.imei,
                'date': format_utcdatetime(instant, request)
            }
            if is_admin:
                popup_str = _("animal_app_position_popup_admin",
                              domain='Ondestan',
                              mapping=parameters)
            else:
                popup_str = _("animal_app_position_popup",
                              domain='Ondestan',
                              mapping=parameters)
            geojson.append({
                "type": "Feature",
                "properties": {
                    "id": animal.id,
                    "name": animal.name,
                    "imei": animal.imei,
                    "owner": animal.user.email,
                    "active": animal.active,
                    "date": format_utcdatetime(instant, request),
                    "popup": get_localizer(request).translate(popup_str)
                },
                "geometry": eval(position)
            })
    return geojson
Пример #3
0
def check_non_communicating_animals():
    manager = transaction.manager
    manager.begin()
    try:
        logger.debug('Checking animals for non communicating ones.')
        animals = get_active_animals()
        for animal in animals:
            if animal.n_positions > 0 and animal.positions[0].date != None:
                if compare_datetime_ago_from_utc(
                        animal.positions[0].date,
                        relativedelta(hours=+no_positions_max_hours)):
                    animal.checks_wo_pos += 1
                    animal.update()
                    logger.info('Animal with id ' + str(animal.id) +
                                ' has not sent new positions in at least ' +
                                str(no_positions_max_hours) + ' hours.')
                    parameters = {
                        'name':
                        animal.user.name,
                        'email':
                        animal.user.email,
                        'animal_name':
                        animal.name if
                        (animal.name != None
                         and animal.name != '') else animal.imei,
                        'date_last_position':
                        format_utcdatetime(animal.positions[0].date,
                                           locale=animal.user.locale),
                        'hours_wo_positions':
                        no_positions_max_hours
                    }
                    ondestan.services.notification_service.\
                        process_notification('gps_no_positions',
                        animal.user.email, animal.checks_wo_pos ==
                        no_positions_web_checks, 2, animal.checks_wo_pos ==
                        no_positions_mail_checks, animal.checks_wo_pos ==
                        no_positions_sms_checks, parameters)

                    admins = ondestan.services.user_service.get_admin_users()
                    for admin in admins:
                        ondestan.services.notification_service.\
                        process_notification('gps_no_positions_admin',
                            admin.email, animal.checks_wo_pos ==
                            no_positions_web_checks, 2, animal.checks_wo_pos ==
                            no_positions_mail_checks, False, parameters)
        manager.commit()
    except:
        manager.abort()
        raise
Пример #4
0
def process_no_coverage_position(position, animal, request):
    if animal.active:
        if (not position.charging and
            get_animal_position_by_date(animal.id, position.date) == None):
            parameters = {'name': animal.user.name,
             'animal_name': animal.name if (animal.name != None and
                            animal.name != '') else animal.imei,
             'date': format_utcdatetime(position.date,
                locale=animal.user.locale)
             }
            ondestan.services.\
            notification_service.process_notification(
                'no_gps_coverage', animal.user.email, True, 2,
                False, False, parameters)
    process_position_general_notifications(position, animal, request)
Пример #5
0
def process_no_coverage_position(position, animal, request):
    if animal.active:
        if (not position.charging and get_animal_position_by_date(
                animal.id, position.date) == None):
            parameters = {
                'name':
                animal.user.name,
                'animal_name':
                animal.name if
                (animal.name != None and animal.name != '') else animal.imei,
                'date':
                format_utcdatetime(position.date, locale=animal.user.locale)
            }
            ondestan.services.\
            notification_service.process_notification(
                'no_gps_coverage', animal.user.email, True, 2,
                False, False, parameters)
    process_position_general_notifications(position, animal, request)
Пример #6
0
def check_non_communicating_animals():
    manager = transaction.manager
    manager.begin()
    try:
        logger.debug('Checking animals for non communicating ones.')
        animals = get_active_animals()
        for animal in animals:
            if animal.n_positions > 0 and animal.positions[0].date != None:
                if compare_datetime_ago_from_utc(animal.positions[0].date,
                    relativedelta(hours=+no_positions_max_hours)):
                    animal.checks_wo_pos += 1
                    animal.update()
                    logger.info('Animal with id ' + str(animal.id) +
                                   ' has not sent new positions in at least ' +
                                   str(no_positions_max_hours) + ' hours.')
                    parameters = {'name': animal.user.name,
                     'email': animal.user.email,
                     'animal_name': animal.name if (animal.name != None and
                                    animal.name != '') else animal.imei,
                     'date_last_position': format_utcdatetime(
                        animal.positions[0].date, locale=animal.user.locale),
                     'hours_wo_positions': no_positions_max_hours
                     }
                    ondestan.services.notification_service.\
                        process_notification('gps_no_positions',
                        animal.user.email, animal.checks_wo_pos ==
                        no_positions_web_checks, 2, animal.checks_wo_pos ==
                        no_positions_mail_checks, animal.checks_wo_pos ==
                        no_positions_sms_checks, parameters)

                    admins = ondestan.services.user_service.get_admin_users()
                    for admin in admins:
                        ondestan.services.notification_service.\
                        process_notification('gps_no_positions_admin',
                            admin.email, animal.checks_wo_pos ==
                            no_positions_web_checks, 2, animal.checks_wo_pos ==
                            no_positions_mail_checks, False, parameters)
        manager.commit()
    except:
        manager.abort()
        raise
Пример #7
0
def save_new_position(position, animal, request):
    if animal.active:
        if get_animal_position_by_date(animal.id, position.date) == None:
            position.animal_id = animal.id
            position.save()
            if (not position.charging and animal.positions[0] == position
                    and animal.positions[0].outside() and
                ((animal.n_positions > 1 and not animal.positions[1].outside())
                 or animal.n_positions == 1)):
                parameters = {
                    'name':
                    animal.user.name,
                    'animal_name':
                    animal.name if (animal.name != None and animal.name != '')
                    else animal.imei,
                    'fancy_date':
                    get_fancy_time_from_utc(position.date,
                                            locale=animal.user.locale),
                    'fancy_date_eval':
                    escape_code_to_eval(
                        "get_fancy_time_from_utc(internal_parse_datetime('" +
                        internal_format_datetime(position.date) +
                        "'), request=request)"),
                    'date':
                    format_utcdatetime(position.date,
                                       locale=animal.user.locale)
                }
                ondestan.services.\
                notification_service.process_notification(
                    'outside_plots', animal.user.email, True, 3,
                    True, True, parameters)
            if position.date != None:
                if not compare_datetime_ago_from_utc(
                        position.date,
                        relativedelta(hours=+no_positions_max_hours)):
                    animal.checks_wo_pos = 0
                    animal.update()
    process_position_general_notifications(position, animal, request)
Пример #8
0
def process_position_general_notifications(position, animal, request):
    if animal.active:
        if position.charging:
            logger.info('Processed update for charging IMEI: ' + animal.imei +
                        ' for date ' + str(position.date))
            return
        aux = get_animal_position_by_date(animal.id, position.date)
        if aux == position or aux == None:
            if position.battery != None and\
                position.battery < medium_battery_barrier:
                if position.battery < low_battery_barrier:
                    if animal.positions[0] == position and\
                        (animal.n_positions == 1 or\
                        animal.positions[1].battery >= low_battery_barrier):
                        parameters = {'name': animal.user.name,
                         'animal_name': animal.name if (animal.name != None and
                                        animal.name != '') else animal.imei,
                         'fancy_date': get_fancy_time_from_utc(position.date,
                                        locale=animal.user.locale),
                         'fancy_date_eval': escape_code_to_eval(
                            "get_fancy_time_from_utc(internal_parse_datetime('"
                            + internal_format_datetime(position.date)
                            + "'), request=request)"),
                         'date': format_utcdatetime(position.date,
                            locale=animal.user.locale),
                         'battery_level': position.battery,
                         'url': request.route_url('map')
                         }
                        ondestan.services.\
                        notification_service.process_notification(
                            'low_battery', animal.user.email, True, 3,
                            True, True, parameters)
                else:
                    if animal.positions[0] == position and\
                        (animal.n_positions == 1 or\
                        animal.positions[1].battery >= medium_battery_barrier):
                        parameters = {'name': animal.user.name,
                         'animal_name': animal.name if (animal.name != None and
                                        animal.name != '') else animal.imei,
                         'fancy_date': get_fancy_time_from_utc(position.date,
                                        locale=animal.user.locale),
                         'fancy_date_eval': escape_code_to_eval(
                            "get_fancy_time_from_utc(internal_parse_datetime('"
                            + internal_format_datetime(position.date)
                            + "'), request=request)"),
                         'date': format_utcdatetime(position.date,
                            locale=animal.user.locale),
                         'battery_level': position.battery,
                         'url': request.route_url('map')
                         }
                        ondestan.services.\
                        notification_service.process_notification(
                            'medium_battery', animal.user.email, True, 2,
                            False, False, parameters)
            if animal.n_positions > 1 and animal.positions[0] == position:
                date_end = position.date
                date_begin = date_end
                aux = position
                for pos in animal.positions:
                    if aux.similar_to_position(pos):
                        date_begin = pos.date
                        aux = pos
                    else:
                        break
                delta = date_end - date_begin
                hours_immobile = delta.days * 24 + delta.seconds / 3600.0
                if hours_immobile > same_position_max_hours:
                    first_immobile = True
                    if animal.n_positions > 2:
                        delta_aux = animal.positions[1].date - date_begin
                        hours_immobile_aux = delta_aux.days * 24 +\
                            delta_aux.seconds / 3600.0
                        first_immobile = hours_immobile_aux <=\
                            same_position_max_hours
                    if first_immobile:
                        parameters = {'name': animal.user.name,
                         'animal_name': animal.name if (animal.name != None and
                                        animal.name != '') else animal.imei,
                         'date_begin': format_utcdatetime(date_begin,
                            locale=animal.user.locale),
                         'hours_immobile': int(hours_immobile),
                         'url': request.route_url('map')
                         }
                        ondestan.services.notification_service.\
                            process_notification('gps_immobile',
                            animal.user.email, True, 2, True,
                            False, parameters)
            logger.info('Processed update for IMEI: ' + animal.imei +
                    ' for date ' + str(position.date))
        else:
            parameters = {'name': animal.user.name,
             'animal_name': animal.name if (animal.name != None and
                            animal.name != '') else animal.imei,
             'date': format_utcdatetime(position.date,
                                        locale=animal.user.locale),
             'url': request.route_url('map')
             }
            ondestan.services.notification_service.process_notification(
                'gps_instant_duplicated', animal.user.email, True, 2, False,
                False, parameters)
            logger.warn('Position already exists for animal: ' + str(animal.id)
                + ' for date ' + str(position.date))
    else:
        # This notification is considered rather confusing than useful
        """parameters = {'name': animal.user.name,
         'animal_name': animal.name if (animal.name != None and
                        animal.name != '') else animal.imei,
         'fancy_date': get_fancy_time_from_utc(position.date,
                        locale=animal.user.locale),
         'fancy_date_eval': escape_code_to_eval(
            "get_fancy_time_from_utc(internal_parse_datetime('"
            + internal_format_datetime(position.date)
            + "'), request=request)"),
         'date': format_utcdatetime(position.date, locale=animal.user.locale),
         'url': request.route_url('map')
         }
        ondestan.services.notification_service.process_notification(
            'gps_inactive_device', animal.user.email, True, 2, False,
            False, parameters)"""
        logger.warn('Processed update for inactive IMEI: ' + animal.imei +
                    ' for date ' + str(position.date))
Пример #9
0
def process_position_general_notifications(position, animal, request):
    if animal.active:
        if position.charging:
            logger.info('Processed update for charging IMEI: ' + animal.imei +
                        ' for date ' + str(position.date))
            return
        aux = get_animal_position_by_date(animal.id, position.date)
        if aux == position or aux == None:
            if position.battery != None and\
                position.battery < medium_battery_barrier:
                if position.battery < low_battery_barrier:
                    if animal.positions[0] == position and\
                        (animal.n_positions == 1 or\
                        animal.positions[1].battery >= low_battery_barrier):
                        parameters = {
                            'name':
                            animal.user.name,
                            'animal_name':
                            animal.name if
                            (animal.name != None
                             and animal.name != '') else animal.imei,
                            'fancy_date':
                            get_fancy_time_from_utc(position.date,
                                                    locale=animal.user.locale),
                            'fancy_date_eval':
                            escape_code_to_eval(
                                "get_fancy_time_from_utc(internal_parse_datetime('"
                                + internal_format_datetime(position.date) +
                                "'), request=request)"),
                            'date':
                            format_utcdatetime(position.date,
                                               locale=animal.user.locale),
                            'battery_level':
                            position.battery,
                            'url':
                            request.route_url('map')
                        }
                        ondestan.services.\
                        notification_service.process_notification(
                            'low_battery', animal.user.email, True, 3,
                            True, True, parameters)
                else:
                    if animal.positions[0] == position and\
                        (animal.n_positions == 1 or\
                        animal.positions[1].battery >= medium_battery_barrier):
                        parameters = {
                            'name':
                            animal.user.name,
                            'animal_name':
                            animal.name if
                            (animal.name != None
                             and animal.name != '') else animal.imei,
                            'fancy_date':
                            get_fancy_time_from_utc(position.date,
                                                    locale=animal.user.locale),
                            'fancy_date_eval':
                            escape_code_to_eval(
                                "get_fancy_time_from_utc(internal_parse_datetime('"
                                + internal_format_datetime(position.date) +
                                "'), request=request)"),
                            'date':
                            format_utcdatetime(position.date,
                                               locale=animal.user.locale),
                            'battery_level':
                            position.battery,
                            'url':
                            request.route_url('map')
                        }
                        ondestan.services.\
                        notification_service.process_notification(
                            'medium_battery', animal.user.email, True, 2,
                            False, False, parameters)
            if animal.n_positions > 1 and animal.positions[0] == position:
                date_end = position.date
                date_begin = date_end
                aux = position
                for pos in animal.positions:
                    if aux.similar_to_position(pos):
                        date_begin = pos.date
                        aux = pos
                    else:
                        break
                delta = date_end - date_begin
                hours_immobile = delta.days * 24 + delta.seconds / 3600.0
                if hours_immobile > same_position_max_hours:
                    first_immobile = True
                    if animal.n_positions > 2:
                        delta_aux = animal.positions[1].date - date_begin
                        hours_immobile_aux = delta_aux.days * 24 +\
                            delta_aux.seconds / 3600.0
                        first_immobile = hours_immobile_aux <=\
                            same_position_max_hours
                    if first_immobile:
                        parameters = {
                            'name':
                            animal.user.name,
                            'animal_name':
                            animal.name if
                            (animal.name != None
                             and animal.name != '') else animal.imei,
                            'date_begin':
                            format_utcdatetime(date_begin,
                                               locale=animal.user.locale),
                            'hours_immobile':
                            int(hours_immobile),
                            'url':
                            request.route_url('map')
                        }
                        ondestan.services.notification_service.\
                            process_notification('gps_immobile',
                            animal.user.email, True, 2, True,
                            False, parameters)
            logger.info('Processed update for IMEI: ' + animal.imei +
                        ' for date ' + str(position.date))
        else:
            parameters = {
                'name':
                animal.user.name,
                'animal_name':
                animal.name if
                (animal.name != None and animal.name != '') else animal.imei,
                'date':
                format_utcdatetime(position.date, locale=animal.user.locale),
                'url':
                request.route_url('map')
            }
            ondestan.services.notification_service.process_notification(
                'gps_instant_duplicated', animal.user.email, True, 2, False,
                False, parameters)
            logger.warn('Position already exists for animal: ' +
                        str(animal.id) + ' for date ' + str(position.date))
    else:
        # This notification is considered rather confusing than useful
        """parameters = {'name': animal.user.name,
         'animal_name': animal.name if (animal.name != None and
                        animal.name != '') else animal.imei,
         'fancy_date': get_fancy_time_from_utc(position.date,
                        locale=animal.user.locale),
         'fancy_date_eval': escape_code_to_eval(
            "get_fancy_time_from_utc(internal_parse_datetime('"
            + internal_format_datetime(position.date)
            + "'), request=request)"),
         'date': format_utcdatetime(position.date, locale=animal.user.locale),
         'url': request.route_url('map')
         }
        ondestan.services.notification_service.process_notification(
            'gps_inactive_device', animal.user.email, True, 2, False,
            False, parameters)"""
        logger.warn('Processed update for inactive IMEI: ' + animal.imei +
                    ' for date ' + str(position.date))
Пример #10
0
def json_animal_charging_positions(request):
    animal_id = request.matchdict['animal_id']
    email = get_user_email(request)
    is_admin = check_permission('admin', request)
    animal = None
    if animal_id != None:
        try:
            animal = animal_service.get_animal_by_id(int(animal_id))
        except ValueError:
            pass
    geojson = []
    if animal != None and (is_admin or animal.user.email == email):
        start = None
        end = None
        if 'start' in request.GET:
            try:
                start = parse_to_utcdatetime(request.GET['start'])
            except ValueError:
                pass
        if 'end' in request.GET:
            try:
                end = parse_to_utcdatetime(request.GET['end'])
            except ValueError:
                pass

        n_positions = animal.n_filter_charging_positions(start, end)
        logger.debug("Found " + str(n_positions) +
                     " charging positions for animal " + str(animal_id))
        if n_positions > 0:
            if animal.name != None and len(animal.name) > 0:
                name = animal.name
            else:
                name = animal.imei
            positions = animal.filter_charging_positions(start, end)
            for position in positions:
                if int(position.battery) == position.battery:
                    position.battery = int(position.battery)
                fancy_date = get_fancy_time_from_utc(position.\
                                                    date, request=request)
                parameters = {
                    'animal_name': name,
                    'name': animal.user.email,
                    'imei': animal.imei,
                    'battery': str(position.battery),
                    'date': fancy_date,
                    'plot': animal.plot.name if animal.plot != None else '---'
                }
                popup_str = _("animal_popup_admin",
                              domain='Ondestan',
                              mapping=parameters)
                geojson.append({
                    "type": "Feature",
                    "properties": {
                        "id": animal.id,
                        "name": animal.name,
                        "imei": animal.imei,
                        "battery": position.battery,
                        "owner": animal.user.email,
                        "active": animal.active,
                        "outside": position.outside(),
                        "date": format_utcdatetime(position.date, request),
                        "fancy_date": fancy_date,
                        "popup": get_localizer(request).translate(popup_str)
                    },
                    "geometry": eval(position.geojson)
                })
                # We return the max number of positions plus one, so it can
                # detect there are more and not just the barrier number
                if len(geojson) == (max_positions + 1):
                    logger.warning(
                        "Too many charging positions requested for animal " +
                        str(animal_id) + ", only the last " +
                        str(max_positions + 1) + " will be returned")
                    break
        else:
            geojson.append({
                "type": "Feature",
                "properties": {
                    "id": animal.id,
                    "name": animal.name,
                    "imei": animal.imei,
                    "battery": None,
                    "owner": animal.user.email,
                    "active": animal.active,
                    "outside": None,
                    "date": None,
                    "fancy_date": None,
                    "popup": None
                },
                "geometry": None
            })
    return geojson
Пример #11
0
def json_animals(request):
    geojson = []
    if (check_permission('admin', request)):
        animals = animal_service.get_all_animals()
        if animals != None:
            logger.debug("Found " + str(len(animals)) +
                         " animals for all users")
            for animal in animals:
                if animal.n_positions > 0:
                    if animal.name != None and len(animal.name) > 0:
                        name = animal.name
                    else:
                        name = animal.imei
                    fancy_date = get_fancy_time_from_utc(animal.positions[0].\
                                                        date, request=request)
                    parameters = {
                        'animal_name': name,
                        'name': animal.user.email,
                        'imei': animal.imei,
                        'battery': str(animal.current_battery_wo_charging),
                        'date': fancy_date,
                        'plot': animal.plot.name if animal.plot != None\
                                else '---'
                    }
                    popup_str = _("animal_popup_admin",
                                  domain='Ondestan',
                                  mapping=parameters)
                    geojson.append({
                        "type": "Feature",
                        "properties": {
                            "id": animal.id,
                            "name": animal.name,
                            "imei": animal.imei,
                            "battery": animal.current_battery,
                            "battery_wo_charging": animal.current_battery_wo_charging,
                            "charging": animal.currently_charging,
                            "owner": animal.user.email,
                            "active": animal.active,
                            "last_date": format_utcdatetime(animal.\
                                                            positions[0].date,
                                                            request),
                            "fancy_last_date": fancy_date,
                            "outside": animal.positions[0].outside(),
                            "popup": get_localizer(request).translate(
                                                                popup_str)
                        },
                        "geometry": eval(animal.positions[0].geojson)
                    })
                else:
                    geojson.append({
                        "type": "Feature",
                        "properties": {
                            "id": animal.id,
                            "name": animal.name,
                            "imei": animal.imei,
                            "battery": None,
                            "battery_wo_charging": None,
                            "charging": None,
                            "owner": animal.user.email,
                            "active": animal.active,
                            "last_date": None,
                            "fancy_last_date": None,
                            "outside": None,
                            "popup": None
                        },
                        "geometry": None
                    })
        else:
            logger.debug("Found no animals for any user")
    else:
        email = get_user_email(request)
        animals = animal_service.get_all_animals(email)
        if animals != None:
            logger.debug("Found " + str(len(animals)) + " animals for user " +
                         email)
            for animal in animals:
                if animal.n_positions > 0:
                    if animal.name != None and len(animal.name) > 0:
                        name = animal.name
                    else:
                        name = animal.imei
                    fancy_date = get_fancy_time_from_utc(animal.positions[0].\
                                                        date, request=request)
                    parameters = {
                        'animal_name': name,
                        'name': animal.user.email,
                        'imei': animal.imei,
                        'battery': str(animal.current_battery_wo_charging),
                        'date': fancy_date,
                        'plot': animal.plot.name if animal.plot != None\
                                else '---'
                    }
                    popup_str = _("animal_popup",
                                  domain='Ondestan',
                                  mapping=parameters)
                    geojson.append({
                        "type": "Feature",
                        "properties": {
                            "id": animal.id,
                            "name": animal.name,
                            "imei": animal.imei,
                            "battery": animal.current_battery,
                            "battery_wo_charging": animal.current_battery_wo_charging,
                            "charging": animal.currently_charging,
                            "owner": animal.user.email,
                            "active": animal.active,
                            "last_date": format_utcdatetime(animal.\
                                                            positions[0].date,
                                                            request),
                            "fancy_last_date": fancy_date,
                            "outside": animal.positions[0].outside(),
                            "popup": get_localizer(request).translate(
                                                                popup_str)
                        },
                        "geometry": eval(animal.positions[0].geojson)
                    })
                else:
                    geojson.append({
                        "type": "Feature",
                        "properties": {
                            "id": animal.id,
                            "name": animal.name,
                            "imei": animal.imei,
                            "battery": None,
                            "battery_wo_charging": None,
                            "charging": None,
                            "owner": animal.user.email,
                            "active": animal.active,
                            "last_date": None,
                            "fancy_last_date": None,
                            "outside": None,
                            "popup": None
                        },
                        "geometry": None
                    })
        else:
            logger.debug("Found no animals for user " + email)
    return geojson