Пример #1
0
def _get_distance_flight(distance):
    return Flight.query() \
        .filter(Flight.pilot == g.user) \
        .filter(Flight.olc_classic_distance >= distance) \
        .order_by(Flight.landing_time) \
        .filter(Flight.is_rankable()) \
        .first()
Пример #2
0
    def run(self, force, date_from, date_to, ids):
        current_app.add_celery()

        if force:
            # invalidate all results
            Flight.query().update({'needs_analysis': True})

        if ids:
            for flight_id in ids:
                self.do(flight_id)
        elif date_from and date_to:
            print date_from
            try:
                date_from = datetime.strptime(date_from, "%Y-%m-%d")
                date_to = datetime.strptime(date_to, "%Y-%m-%d")
            except:
                print "Cannot parse date."
                quit()

            q = db.session.query(Flight)
            q = q.filter(Flight.takeoff_time >= date_from) \
                 .filter(Flight.takeoff_time <= date_to)

            for flight in q:
                self.do(flight.id)
        else:
            for flight in Flight.query(needs_analysis=True):
                self.do(flight.id)
Пример #3
0
    def run(self, force, date_from, date_to, ids):
        current_app.add_celery()

        if force:
            # invalidate all results
            Flight.query().update({'needs_analysis': True})

        if ids:
            for flight_id in ids:
                self.do(flight_id)
        elif date_from and date_to:
            print date_from
            try:
                date_from = datetime.strptime(date_from, "%Y-%m-%d")
                date_to = datetime.strptime(date_to, "%Y-%m-%d")
            except:
                print "Cannot parse date."
                quit()

            q = db.session.query(Flight)
            q = q.filter(Flight.takeoff_time >= date_from) \
                 .filter(Flight.takeoff_time <= date_to)

            for flight in q:
                self.do(flight.id)
        else:
            for flight in Flight.query(needs_analysis=True):
                self.do(flight.id)
Пример #4
0
def _get_distance_flight(distance):
    return Flight.query() \
        .filter(Flight.pilot == g.user) \
        .filter(Flight.olc_classic_distance >= distance) \
        .order_by(Flight.landing_time) \
        .filter(Flight.is_rankable()) \
        .first()
Пример #5
0
def find_meetings(flight_id):
    logger.info("Searching for near flights of flight %d" % flight_id)

    flight = Flight.get(flight_id)

    # Update FlightPathChunks of current flight
    FlightPathChunks.update_flight_path(flight)

    other_flights = FlightPathChunks.get_near_flights(flight)

    # delete all previous detected points between src and dst
    for key in other_flights:
        FlightMeetings.query() \
            .filter(or_(and_(FlightMeetings.source == flight, FlightMeetings.destination_id == key),
                        and_(FlightMeetings.destination == flight, FlightMeetings.source_id == key))) \
            .delete()

    # Insert new meetings into table
    for flight_id, meetings in other_flights.iteritems():
        other_flight = Flight.get(flight_id)

        for meeting in meetings:
            FlightMeetings.add_meeting(flight, other_flight, meeting['times'][0], meeting['times'][-1])

    db.session.commit()
Пример #6
0
def find_meetings(flight_id):
    logger.info("Searching for near flights of flight %d" % flight_id)

    flight = Flight.get(flight_id)

    # Update FlightPathChunks of current flight
    FlightPathChunks.update_flight_path(flight)

    other_flights = FlightPathChunks.get_near_flights(flight)

    # delete all previous detected points between src and dst
    for key in other_flights:
        FlightMeetings.query().filter(
            or_(
                and_(
                    FlightMeetings.source == flight,
                    FlightMeetings.destination_id == key,
                ),
                and_(
                    FlightMeetings.destination == flight,
                    FlightMeetings.source_id == key,
                ),
            )).delete()

    # Insert new meetings into table
    for flight_id, meetings in other_flights.items():
        other_flight = Flight.get(flight_id)

        for meeting in meetings:
            FlightMeetings.add_meeting(flight, other_flight,
                                       meeting["times"][0],
                                       meeting["times"][-1])

    db.session.commit()
Пример #7
0
def _distance_flight(user, distance, schema):
    flight = (Flight.query().filter(Flight.pilot == user).filter(
        Flight.olc_classic_distance >= distance).order_by(
            Flight.landing_time).filter(Flight.is_rankable()).first())

    if flight:
        return schema.dump(flight).data
Пример #8
0
def _distance_flight(user, distance, schema):
    flight = Flight.query() \
        .filter(Flight.pilot == user) \
        .filter(Flight.olc_classic_distance >= distance) \
        .order_by(Flight.landing_time) \
        .filter(Flight.is_rankable()) \
        .first()

    if flight:
        return schema.dump(flight).data
Пример #9
0
    def run(self, force, ids):
        current_app.add_celery()

        if force:
            # invalidate all results
            Flight.query().update({'needs_analysis': True})

        if ids:
            for flight_id in ids:
                self.do(flight_id)
        else:
            for flight in Flight.query(needs_analysis=True):
                self.do(flight.id)
Пример #10
0
    def run(self, force, ids):
        current_app.add_celery()

        if force:
            # invalidate all results
            Flight.query().update({'needs_analysis': True})

        if ids:
            for flight_id in ids:
                self.do(flight_id)
        else:
            for flight in Flight.query(needs_analysis=True):
                self.do(flight.id)
Пример #11
0
def _get_last_year_statistics():
    query = db.session.query(func.count('*').label('flights'),
                             func.sum(Flight.olc_classic_distance).label('distance'),
                             func.sum(Flight.duration).label('duration')) \
                      .filter(Flight.pilot == g.user) \
                      .filter(Flight.date_local > (date.today() - timedelta(days=365))) \
                      .filter(Flight.is_rankable()) \
                      .first()

    last_year_statistics = dict(flights=0,
                                distance=0,
                                duration=timedelta(0),
                                speed=0)

    if query and query.flights > 0:
        duration_seconds = query.duration.days * 24 * 3600 + query.duration.seconds

        if duration_seconds > 0:
            last_year_statistics['speed'] = float(query.distance) / duration_seconds

        last_year_statistics['flights'] = query.flights
        last_year_statistics['distance'] = query.distance
        last_year_statistics['duration'] = query.duration

        last_year_statistics['average_distance'] = query.distance / query.flights
        last_year_statistics['average_duration'] = query.duration / query.flights

    return last_year_statistics
Пример #12
0
def _get_last_year_statistics():
    query = db.session.query(func.count('*').label('flights'),
                             func.sum(Flight.olc_classic_distance).label('distance'),
                             func.sum(Flight.duration).label('duration')) \
                      .filter(Flight.pilot == g.user) \
                      .filter(Flight.date_local > (date.today() - timedelta(days=365))) \
                      .filter(Flight.is_rankable()) \
                      .first()

    last_year_statistics = dict(flights=0,
                                distance=0,
                                duration=timedelta(0),
                                speed=0)

    if query and query.flights > 0:
        duration_seconds = query.duration.days * 24 * 3600 + query.duration.seconds

        if duration_seconds > 0:
            last_year_statistics['speed'] = float(
                query.distance) / duration_seconds

        last_year_statistics['flights'] = query.flights
        last_year_statistics['distance'] = query.distance
        last_year_statistics['duration'] = query.duration

        last_year_statistics[
            'average_distance'] = query.distance / query.flights
        last_year_statistics[
            'average_duration'] = query.duration / query.flights

    return last_year_statistics
Пример #13
0
def _update_flight(flight_id, model_id, registration, competition_id,
                   takeoff_time, scoring_start_time,
                   scoring_end_time, landing_time):
    # Get flight from database and check if it is writable
    flight = Flight.get(flight_id)

    if not flight or not flight.is_writable(g.current_user):
        return False

    # Parse model, registration and competition ID
    if model_id == 0:
        model_id = None

    if registration is not None:
        registration = registration.strip()
        if not 0 < len(registration) <= 32:
            registration = None

    if competition_id is not None:
        competition_id = competition_id.strip()
        if not 0 < len(competition_id) <= 5:
            competition_id = None

    # Set new values
    flight.model_id = model_id
    flight.registration = registration
    flight.competition_id = competition_id
    flight.time_modified = datetime.utcnow()

    # Update times only if they are reasonable and have been changed...
    trigger_analysis = False

    if takeoff_time and scoring_start_time and scoring_end_time and landing_time \
       and takeoff_time <= scoring_start_time <= scoring_end_time <= landing_time \
       and (flight.takeoff_time != takeoff_time
            or flight.scoring_start_time != scoring_start_time
            or flight.scoring_end_time != scoring_end_time
            or flight.landing_time != landing_time):

        flight.takeoff_time = takeoff_time
        flight.scoring_start_time = scoring_start_time
        flight.scoring_end_time = scoring_end_time
        flight.landing_time = landing_time

        trigger_analysis = True

    flight.privacy_level = Flight.PrivacyLevel.PUBLIC

    db.session.commit()

    if trigger_analysis:
        analyse_flight(flight)

    try:
        tasks.analyse_flight.delay(flight.id)
        tasks.find_meetings.delay(flight.id)
    except ConnectionError:
        current_app.logger.info('Cannot connect to Redis server')

    return True
Пример #14
0
def _list():
    query = (Notification.query(
        recipient_id=request.user_id).join("event").options(
            contains_eager("event")).options(
                subqueryload("event.actor")).outerjoin(Event.flight).options(
                    contains_eager("event.flight")).filter(
                        or_(Event.flight == None,
                            Flight.is_rankable())).order_by(Event.time.desc()))

    query = _filter_query(query, request.args)

    page = request.args.get("page", type=int, default=1)
    per_page = request.args.get("per_page", type=int, default=50)

    query = query.limit(per_page)
    query = query.offset((page - 1) * per_page)

    def get_event(notification):
        event = notification.event
        event.unread = notification.time_read is None
        return event

    events = list(
        convert_event(get_event(notification)) for notification in query)

    return jsonify(events=events)
Пример #15
0
def _list():
    query = (
        Notification.query(recipient_id=request.user_id)
        .join("event")
        .options(contains_eager("event"))
        .options(subqueryload("event.actor"))
        .outerjoin(Event.flight)
        .options(contains_eager("event.flight"))
        .filter(or_(Event.flight == None, Flight.is_rankable()))
        .order_by(Event.time.desc())
    )

    query = _filter_query(query, request.args)

    page = request.args.get("page", type=int, default=1)
    per_page = request.args.get("per_page", type=int, default=50)

    query = query.limit(per_page)
    query = query.offset((page - 1) * per_page)

    def get_event(notification):
        event = notification.event
        event.unread = notification.time_read is None
        return event

    events = list(convert_event(get_event(notification)) for notification in query)

    return jsonify(events=events)
Пример #16
0
def analyse_flight(flight_id, full=2048, triangle=6144, sprint=512):
    logger.info("Analysing flight %d" % flight_id)

    if analysis.analyse_flight(Flight.get(flight_id), full, triangle, sprint):
        db.session.commit()
    else:
        logger.warn("Analysis of flight %d failed." % flight_id)
Пример #17
0
def _get_result_Flight(table, table_column, year=None):
    subq = (
        db.session.query(
            getattr(Flight, table_column),
            func.count("*").label("count"),
            func.sum(Flight.index_score).label("total"),
        ).group_by(getattr(Flight, table_column)).outerjoin(
            Flight.model)  #glider model
        .filter(Flight.is_rankable()))

    if isinstance(year, int):
        year_start = date(year, 1, 1)
        year_end = date(year, 12, 31)
        subq = subq.filter(Flight.date_local >= year_start).filter(
            Flight.date_local <= year_end)

    subq = subq.subquery()

    result = db.session.query(
        table,
        subq.c.count,
        subq.c.total,
        over(func.rank(), order_by=desc("total")).label("rank"),
    ).join((subq, getattr(subq.c, table_column) == table.id))

    if table == User:
        result = result.outerjoin(table.club)
        result = result.options(eagerload(table.club))

    return result
Пример #18
0
def _list():
    query = Notification.query(recipient_id=request.user_id) \
        .join('event') \
        .options(contains_eager('event')) \
        .options(subqueryload('event.actor')) \
        .outerjoin(Event.flight) \
        .options(contains_eager('event.flight')) \
        .filter(or_(Event.flight == None, Flight.is_rankable())) \
        .order_by(Event.time.desc())

    query = _filter_query(query, request.args)

    page = request.args.get('page', type=int, default=1)
    per_page = request.args.get('per_page', type=int, default=50)

    query = query.limit(per_page)
    query = query.offset((page - 1) * per_page)

    def get_event(notification):
        event = notification.event
        event.unread = (notification.time_read is None)
        return event

    events = map(get_event, query)

    return jsonify(events=(map(convert_event, events)))
Пример #19
0
def analyse_flight(flight_id, full=2048, triangle=6144, sprint=512):
    logger.info("Analysing flight %d" % flight_id)

    if analysis.analyse_flight(Flight.get(flight_id), full, triangle, sprint):
        db.session.commit()
    else:
        logger.warn("Analysis of flight %d failed." % flight_id)
Пример #20
0
def _get_takeoff_locations(user):
    locations = Location.get_clustered_locations(
        Flight.takeoff_location_wkt,
        filter=and_(Flight.pilot == user, Flight.is_rankable()),
    )

    return [loc.to_lonlat() for loc in locations]
Пример #21
0
def club_change_post(form):
    old_club_id = g.user.club_id
    new_club_id = form.club.data if form.club.data != 0 else None

    if old_club_id == new_club_id:
        return redirect(url_for('.club', user=g.user_id))

    g.user.club_id = new_club_id

    create_club_join_event(new_club_id, g.user)

    # assign the user's new club to all of his flights that have
    # no club yet
    flights = Flight.query().join(IGCFile)
    flights = flights.filter(and_(Flight.club_id == None,
                                  or_(Flight.pilot_id == g.user.id,
                                      IGCFile.owner_id == g.user.id)))
    for flight in flights:
        flight.club_id = g.user.club_id

    db.session.commit()

    flash(_('New club was saved.'), 'success')

    return redirect(url_for('.club', user=g.user_id))
Пример #22
0
def index():
    query = Event.query() \
        .options(subqueryload('actor')) \
        .options(subqueryload('user')) \
        .options(subqueryload('club')) \
        .outerjoin(Event.flight) \
        .options(contains_eager(Event.flight)) \
        .filter(or_(Event.flight == None, Flight.is_rankable())) \
        .order_by(Event.time.desc())

    query = _filter_query(query, request.args)

    page = request.args.get('page', type=int, default=1)
    per_page = request.args.get('per_page', type=int, default=50)

    events = query.limit(per_page).offset((page - 1) * per_page).all()
    events_count = len(events)

    if request.args.get('grouped', True, type=str_to_bool):
        events = group_events(events)

    template_vars = dict(events=events, types=Event.Type)

    if page > 1:
        template_vars['prev_page'] = page - 1
    if events_count == per_page:
        template_vars['next_page'] = page + 1

    return render_template('timeline/list.jinja', **template_vars)
Пример #23
0
def one(igc_file, **kwargs):
    return Flight(
        igc_file=igc_file,
        pilot=igc_file.owner,
        date_local=date(2011, 6, 18),
        takeoff_time=datetime(2011, 6, 18, 9, 11, 23),
        landing_time=datetime(2011, 6, 18, 9, 15, 40),
        time_created=datetime(2011, 6, 19, 11, 23, 45),
        timestamps='',
        locations=
        ('0102000020E6100000380000000D43014D84FD384011E8E00B933D4B40D80CA06485FD38402B831180'
         '923D4B40D80CA06485FD3840F64CB097933D4B401C70B3EA73FD384034A1DD93873D4B40CF5D555555'
         'FD38409FCCD32B653D4B4026FD00032EFD3840DFDF34EF383D4B40E817550BFFFC3840D530EADF083D'
         '4B404CE4B256C7FC3840CC819FD0D83C4B40B0B010A28FFC38408F9CF3D8A93C4B4069AD98966BFC38'
         '4003E6B5847C3C4B40C86A105839FC38402A5EE6D3503C4B40BFBBC54809FC384006146B50213C4B40'
         '5BCD6A06CBFB384095F85D70F33B4B40614BD2948AFB38409CC677C1CD3B4B4037A2BEC445FB38403B'
         '28CF41AA3B4B40AEAAB437F8FA3840772C4A7B833B4B4024B3AAAAAAFA38407FFA63CC5D3B4B40FE18'
         '7D6460FA384085C87D1D383B4B40B375A0D306FA38400A8FA429153B4B40DA5C5227A0F9384027E908'
         '65F43A4B4093C85B2041F93840C64A60E5D03A4B40E4C7A248E4F8384099E2184EAC3A4B4002918888'
         '88F838406D7AD1B6873A4B40FD5FA50718F838405AADBA93623A4B40C5F8609EA8F73840AB3D80B740'
         '3A4B40585BBB4C3AF738409261830A213A4B40B887B412CDF63840484F2575023A4B405508DBD453F6'
         '3840307328C8E2394B40C3618638D6F53840E560CA32C4394B404CA614D372F538402065456C9D394B'
         '403EE8E33948F5384095AE071870394B40E9B7B99034F538402293FA3742394B404906B04D3DF53840'
         'D7809CA223394B401D101870A9F538401FF395B20C394B40AA38057E67F6384023027C3C07394B40D4'
         '9494405DF738409CEBA26D0F394B40C51A5E951EF838407423C05B20394B403A674EF6BCF838407B82'
         '58A835394B4051D4C99E17F9384051BA759646394B4001B3857FFEF838408CE0EDC695394B40657FE3'
         'CAC6F838407D44BA24E1394B404E1268226CF8384005EC11EF133A4B4053FF50B5F0F7384013AA4288'
         '3E3A4B40610A065C6AF73840A36F6666663A4B4063578A69B9F63840EF81C4FB843A4B406DC2DA8AFD'
         'F538406D7AD1B6873A4B4014D04E653EF53840C05A499D803A4B404953345B8CF43840B4ECCAC6703A'
         '4B4033553AB7F6F338402F9525BF583A4B40FFFCDBD781F33840E482C7293A3A4B40E88F602F27F338'
         '4083E41EAA163A4B40AEB99AC1F2F238400DBA2B40EE394B405A897018DFF238407CF40762C6394B40'
         'B4C8804BEDF23840EB2EE4839E394B409C7D029A08F33840E4CF4B3789394B40B3EA7D4263F338403D'
         'BFA9A77C394B40'),
    ).apply_kwargs(kwargs)
Пример #24
0
def _largest_flight(user, schema):
    flight = user.get_largest_flights() \
        .filter(Flight.is_rankable()) \
        .first()

    if flight:
        return schema.dump(flight).data
Пример #25
0
def _get_takeoff_locations(user):
    locations = Location.get_clustered_locations(
        Flight.takeoff_location_wkt,
        filter=and_(Flight.pilot == user, Flight.is_rankable()),
    )

    return [loc.to_lonlat() for loc in locations]
Пример #26
0
def _largest_flight(user, schema):
    flight = user.get_largest_flights() \
        .filter(Flight.is_rankable()) \
        .first()

    if flight:
        return schema.dump(flight).data
Пример #27
0
def _get_result(model, flight_field, year=None):
    subq = db.session \
        .query(getattr(Flight, flight_field),
               func.count('*').label('count'),
               func.sum(Flight.index_score).label('total')) \
        .group_by(getattr(Flight, flight_field)) \
        .outerjoin(Flight.model) \
        .filter(Flight.is_rankable())

    if isinstance(year, int):
        year_start = date(year, 1, 1)
        year_end = date(year, 12, 31)
        subq = subq.filter(Flight.date_local >= year_start) \
                   .filter(Flight.date_local <= year_end)

    subq = subq.subquery()

    result = db.session \
        .query(model, subq.c.count, subq.c.total,
               over(func.rank(), order_by=desc('total')).label('rank')) \
        .join((subq, getattr(subq.c, flight_field) == model.id))

    if model == User:
        result = result.outerjoin(model.club)
        result = result.options(eagerload(model.club))

    return result
Пример #28
0
def update():
    flight_id_list = request.values.getlist('flight_id')
    model_list = request.values.getlist('model')
    registration_list = request.values.getlist('registration')
    competition_id_list = request.values.getlist('competition_id')

    if (flight_id_list is None
            or len(flight_id_list) != len(model_list)
            or len(flight_id_list) != len(registration_list)):
        flash(_('Sorry, some error happened when updating your flight(s). Please contact a administrator for help.'), 'warning')
        return redirect('/flights/latest')

    for index, id in enumerate(flight_id_list):
        # Parse flight id

        try:
            id = int(id)
        except ValueError:
            continue

        # Get flight from database and check if it is writable

        flight = Flight.get(id)

        if not flight or not flight.is_writable(g.current_user):
            continue

        # Parse model, registration and competition ID

        try:
            model_id = int(model_list[index])
        except ValueError:
            model_id = None

        if model_id == 0:
            model_id = None

        registration = registration_list[index]
        if registration is not None:
            registration = registration.strip()
            if not 0 < len(registration) < 32:
                registration = None

        competition_id = competition_id_list[index]
        if competition_id is not None:
            competition_id = competition_id.strip()
            if not 0 < len(competition_id) < 5:
                competition_id = None

        # Set new values

        flight.model_id = model_id
        flight.registration = registration
        flight.competition_id = competition_id
        flight.time_modified = datetime.utcnow()

    db.session.commit()

    flash(_('Your flight(s) have been successfully updated.'))
    return redirect('/flights/latest')
Пример #29
0
def club_change_post(form):
    old_club_id = g.user.club_id
    new_club_id = form.club.data if form.club.data != 0 else None

    if old_club_id == new_club_id:
        return redirect(url_for('.club', user=g.user_id))

    g.user.club_id = new_club_id

    create_club_join_event(new_club_id, g.user)

    # assign the user's new club to all of his flights that have
    # no club yet
    flights = Flight.query().join(IGCFile)
    flights = flights.filter(and_(Flight.club_id == None,
                                  or_(Flight.pilot_id == g.user.id,
                                      IGCFile.owner_id == g.user.id)))
    for flight in flights:
        flight.club_id = g.user.club_id

    db.session.commit()

    flash(_('New club was saved.'), 'success')

    return redirect(url_for('.club', user=g.user_id))
Пример #30
0
def _update_flight(flight_id, model_id, registration, competition_id):
    # Get flight from database and check if it is writable
    flight = Flight.get(flight_id)

    if not flight or not flight.is_writable(g.current_user):
        return False

    # Parse model, registration and competition ID
    if model_id == 0:
        model_id = None

    if registration is not None:
        registration = registration.strip()
        if not 0 < len(registration) <= 32:
            registration = None

    if competition_id is not None:
        competition_id = competition_id.strip()
        if not 0 < len(competition_id) <= 5:
            competition_id = None

    # Set new values
    flight.model_id = model_id
    flight.registration = registration
    flight.competition_id = competition_id
    flight.time_modified = datetime.utcnow()

    db.session.commit()

    return True
Пример #31
0
def list():
    query = Notification.query(recipient_id=request.user_id) \
        .join('event') \
        .options(contains_eager('event')) \
        .options(subqueryload('event.actor')) \
        .outerjoin(Event.flight) \
        .options(contains_eager('event.flight')) \
        .filter(or_(Event.flight == None, Flight.is_rankable())) \
        .order_by(Event.time.desc())

    query = _filter_query(query, request.args)

    page = request.args.get('page', type=int, default=1)
    per_page = request.args.get('per_page', type=int, default=50)

    query = query.limit(per_page)
    query = query.offset((page - 1) * per_page)

    def get_event(notification):
        event = notification.event
        event.unread = (notification.time_read is None)
        return event

    events = map(get_event, query)

    return jsonify(events=(map(convert_event, events)))
Пример #32
0
def _get_result(model, flight_field, year=None):
    subq = db.session \
        .query(getattr(Flight, flight_field),
               func.count('*').label('count'),
               func.sum(Flight.index_score).label('total')) \
        .group_by(getattr(Flight, flight_field)) \
        .outerjoin(Flight.model) \
        .filter(Flight.is_rankable())

    if isinstance(year, int):
        year_start = date(year, 1, 1)
        year_end = date(year, 12, 31)
        subq = subq.filter(Flight.date_local >= year_start) \
                   .filter(Flight.date_local <= year_end)

    subq = subq.subquery()

    result = db.session \
        .query(model, subq.c.count, subq.c.total,
               over(func.rank(), order_by=desc('total')).label('rank')) \
        .join((subq, getattr(subq.c, flight_field) == model.id))

    if model == User:
        result = result.outerjoin(model.club)
        result = result.options(eagerload(model.club))

    return result
Пример #33
0
def check_update_form(prefix, flight_id, name, status):
    if not flight_id:
        return None, None, None

    # Get flight from database and check if it is writable
    flight = Flight.get(flight_id)

    if not flight:
        abort(404)

    if status == UploadStatus.DUPLICATE:
        return flight, None, None

    else:
        if not flight.is_writable(g.current_user):
            abort(403)

        form = UploadUpdateForm(prefix=str(prefix), obj=flight)
        trace = _get_flight_path(flight)

        # Force takeoff_time and landing_time to be within the igc file limits
        if form.takeoff_time.data < trace['igc_start_time']:
            form.takeoff_time.data = trace['igc_start_time']

        if form.landing_time.data > trace['igc_end_time']:
            form.landing_time.data = trace['igc_end_time']

        return flight, trace, form
Пример #34
0
def index(page=None, id=None):
    if 'application/json' not in request.headers.get('Accept', ''):
        return render_template('ember-page.jinja', active_page='statistics')

    name = None

    query = db.session.query(Flight.year.label('year'),
                             func.count('*').label('flights'),
                             func.count(distinct(Flight.pilot_id)).label('pilots'),
                             func.sum(Flight.olc_classic_distance).label('distance'),
                             func.sum(Flight.duration).label('duration'))

    pilots_query = db.session.query(func.count(distinct(Flight.pilot_id)))

    if page == 'pilot':
        pilot = get_requested_record(User, id)
        name = unicode(pilot)
        query = query.filter(Flight.pilot_id == pilot.id)

    elif page == 'club':
        club = get_requested_record(Club, id)
        name = unicode(club)
        query = query.filter(Flight.club_id == club.id)
        pilots_query = pilots_query.filter(Flight.club_id == club.id)

    elif page == 'airport':
        airport = get_requested_record(Airport, id)
        name = unicode(airport)
        query = query.filter(Flight.takeoff_airport_id == airport.id)
        pilots_query = pilots_query.filter(Flight.takeoff_airport_id == airport.id)

    elif page is not None:
        abort(404)

    query = query.filter(Flight.is_rankable())

    query = query.group_by(Flight.year).order_by(Flight.year.desc())

    if page == 'pilot':
        sum_pilots = 0
    else:
        sum_pilots = pilots_query.scalar()

    list = []
    for row in query:
        row.average_distance = row.distance / row.flights
        row.average_duration = row.duration / row.flights

        list.append({
            'year': row.year,
            'flights': row.flights,
            'distance': row.distance,
            'duration': row.duration.total_seconds(),
            'pilots': row.pilots,
            'average_distance': row.distance / row.flights,
            'average_duration': row.duration.total_seconds() / row.flights,
        })

    return jsonify(name=name, years=list, sumPilots=sum_pilots)
Пример #35
0
def _patch_query(q):
    current_user = User.get(request.user_id) if request.user_id else None

    return (
        q.join(Flight.igc_file)
        .options(contains_eager(Flight.igc_file))
        .filter(Flight.is_viewable(current_user))
    )
Пример #36
0
def _patch_query(q):
    current_user = User.get(request.user_id) if request.user_id else None

    return (
        q.join(Flight.igc_file)
        .options(contains_eager(Flight.igc_file))
        .filter(Flight.is_viewable(current_user))
    )
Пример #37
0
def _get_near_flights(flight, location, time, max_distance=1000):
    # calculate max_distance in degrees at the earth's sphere (approximate,
    # cutoff at +-85 deg)
    max_distance_deg = (max_distance / METERS_PER_DEGREE) / \
        math.cos(math.radians(min(abs(location.latitude), 85)))

    # the distance filter is geometric only, so max_distance must be given in
    # SRID units (which is degrees for WGS84). The filter will be more and more
    # inaccurate further to the poles. But it's a lot faster than the geograpic
    # filter...

    result = Flight.query() \
        .options(undefer_group('path')) \
        .filter(Flight.id != flight.id) \
        .filter(Flight.takeoff_time <= time) \
        .filter(Flight.landing_time >= time) \
        .filter(func.ST_DWithin(Flight.locations,
                                location.to_wkt_element(),
                                max_distance_deg))

    result = _patch_query(result)

    flights = []
    for flight in result:
        # find point closest to given time
        closest = min(range(len(flight.timestamps)),
                      key=lambda x: abs((flight.timestamps[x] - time).total_seconds()))

        trace = to_shape(flight.locations).coords

        if closest == 0 or closest == len(trace) - 1:
            point = trace[closest]
        else:
            # interpolate flight trace between two fixes
            next_smaller = closest if flight.timestamps[closest] < time else closest - 1
            next_larger = closest if flight.timestamps[closest] > time else closest + 1
            dx = (time - flight.timestamps[next_smaller]).total_seconds() / \
                 (flight.timestamps[next_larger] - flight.timestamps[next_smaller]).total_seconds()

            point_next = trace[closest]
            point_prev = trace[closest]

            point = [point_prev[0] + (point_next[0] - point_prev[0]) * dx,
                     point_prev[1] + (point_next[1] - point_prev[1]) * dx]

        point_distance = location.geographic_distance(
            Location(latitude=point[1], longitude=point[0]))

        if point_distance > max_distance:
            continue

        flights.append(flight)

        # limit to 5 flights
        if len(flights) == 5:
            break

    return flights
Пример #38
0
def _get_near_flights(flight, location, time, max_distance=1000):
    # calculate max_distance in degrees at the earth's sphere (approximate,
    # cutoff at +-85 deg)
    max_distance_deg = (max_distance / METERS_PER_DEGREE) / \
        math.cos(math.radians(min(abs(location.latitude), 85)))

    # the distance filter is geometric only, so max_distance must be given in
    # SRID units (which is degrees for WGS84). The filter will be more and more
    # inaccurate further to the poles. But it's a lot faster than the geograpic
    # filter...

    result = Flight.query() \
        .options(undefer_group('path')) \
        .filter(Flight.id != flight.id) \
        .filter(Flight.takeoff_time <= time) \
        .filter(Flight.landing_time >= time) \
        .filter(func.ST_DWithin(Flight.locations,
                                location.to_wkt_element(),
                                max_distance_deg))

    result = _patch_query(result)

    flights = []
    for flight in result:
        # find point closest to given time
        closest = min(range(len(flight.timestamps)),
                      key=lambda x: abs((flight.timestamps[x] - time).total_seconds()))

        trace = to_shape(flight.locations).coords

        if closest == 0 or closest == len(trace) - 1:
            point = trace[closest]
        else:
            # interpolate flight trace between two fixes
            next_smaller = closest if flight.timestamps[closest] < time else closest - 1
            next_larger = closest if flight.timestamps[closest] > time else closest + 1
            dx = (time - flight.timestamps[next_smaller]).total_seconds() / \
                 (flight.timestamps[next_larger] - flight.timestamps[next_smaller]).total_seconds()

            point_next = trace[closest]
            point_prev = trace[closest]

            point = [point_prev[0] + (point_next[0] - point_prev[0]) * dx,
                     point_prev[1] + (point_next[1] - point_prev[1]) * dx]

        point_distance = location.geographic_distance(
            Location(latitude=point[1], longitude=point[0]))

        if point_distance > max_distance:
            continue

        flights.append(flight)

        # limit to 5 flights
        if len(flights) == 5:
            break

    return flights
Пример #39
0
def index(page=None, id=None):
    name = None

    query = db.session.query(
        Flight.year.label("year"),
        func.count("*").label("flights"),
        func.count(distinct(Flight.pilot_id)).label("pilots"),
        func.sum(Flight.olc_classic_distance).label("distance"),
        func.sum(Flight.duration).label("duration"),
    )

    pilots_query = db.session.query(func.count(distinct(Flight.pilot_id)))

    if page == "pilot":
        pilot = get_requested_record(User, id)
        name = pilot.name
        query = query.filter(Flight.pilot_id == pilot.id)

    elif page == "club":
        club = get_requested_record(Club, id)
        name = club.name
        query = query.filter(Flight.club_id == club.id)
        pilots_query = pilots_query.filter(Flight.club_id == club.id)

    elif page == "airport":
        airport = get_requested_record(Airport, id)
        name = airport.name
        query = query.filter(Flight.takeoff_airport_id == airport.id)
        pilots_query = pilots_query.filter(Flight.takeoff_airport_id == airport.id)

    elif page is not None:
        abort(404)

    query = query.filter(Flight.is_rankable())

    query = query.group_by(Flight.year).order_by(Flight.year.desc())

    if page == "pilot":
        sum_pilots = 0
    else:
        sum_pilots = pilots_query.scalar()

    list = []
    for row in query:
        list.append(
            {
                "year": row.year,
                "flights": row.flights,
                "distance": row.distance,
                "duration": row.duration.total_seconds(),
                "pilots": row.pilots,
                "average_distance": row.distance / row.flights,
                "average_duration": row.duration.total_seconds() / row.flights,
            }
        )

    return jsonify(name=name, years=list, sumPilots=sum_pilots)
Пример #40
0
def _quick_stats(user):
    result = (db.session.query(
        func.count("*").label("flights"),
        func.sum(Flight.olc_classic_distance).label("distance"),
        func.sum(Flight.duration).label("duration"),
    ).filter(Flight.pilot == user).filter(
        Flight.date_local > (date.today() - timedelta(days=365))).filter(
            Flight.is_rankable()).one())

    return QuickStatsSchema().dump(result).data
Пример #41
0
def _quick_stats():
    result = db.session.query(func.count('*').label('flights'),
                              func.sum(Flight.olc_classic_distance).label('distance'),
                              func.sum(Flight.duration).label('duration')) \
        .filter(Flight.pilot == g.user) \
        .filter(Flight.date_local > (date.today() - timedelta(days=365))) \
        .filter(Flight.is_rankable()) \
        .one()

    return QuickStatsSchema().dump(result).data
Пример #42
0
def _quick_stats(user):
    result = db.session.query(func.count('*').label('flights'),
                              func.sum(Flight.olc_classic_distance).label('distance'),
                              func.sum(Flight.duration).label('duration')) \
        .filter(Flight.pilot == user) \
        .filter(Flight.date_local > (date.today() - timedelta(days=365))) \
        .filter(Flight.is_rankable()) \
        .one()

    return QuickStatsSchema().dump(result).data
Пример #43
0
def latest():
    query = db.session \
        .query(func.max(Flight.date_local).label('date')) \
        .filter(Flight.takeoff_time < datetime.utcnow()) \
        .join(Flight.igc_file) \
        .filter(Flight.is_listable(g.current_user))

    date_ = query.one().date
    if not date_:
        date_ = datetime.utcnow()

    return date(date_, latest=True)
Пример #44
0
def latest():
    query = db.session \
        .query(func.max(Flight.date_local).label('date')) \
        .filter(Flight.takeoff_time < datetime.utcnow()) \
        .join(Flight.igc_file) \
        .filter(Flight.is_listable(g.current_user))

    date_ = query.one().date
    if not date_:
        date_ = datetime.utcnow()

    return date(date_, latest=True)
Пример #45
0
def analyse_flight(flight_id, full=2048, triangle=6144, sprint=512):
    logger.info("Analysing flight %d" % flight_id)

    flight = Flight.get(flight_id)
    success = analysis.analyse_flight(flight, full, triangle, sprint)

    if not success:
        logger.warn("Analysis of flight %d failed." % flight_id)
        return

    unlock_flight_achievements(flight)

    db.session.commit()
Пример #46
0
def latest():
    current_user = User.get(request.user_id) if request.user_id else None

    query = (db.session.query(func.max(
        Flight.date_local).label("date")).filter(
            Flight.takeoff_time < datetime.utcnow()).join(
                Flight.igc_file).filter(Flight.is_listable(current_user)))

    date_ = query.one().date
    if not date_:
        date_ = datetime.utcnow()

    return date(date_)
Пример #47
0
def flights_js():
    flights = Flight.query() \
                    .filter(Flight.is_rankable())

    # Filter by user
    user_id = request.values.get('user', type=int)
    if user_id:
        user = User.get(user_id)
        if not user:
            abort(404)

        flights = flights.filter(or_(
            Flight.pilot == user,
            Flight.co_pilot == user
        ))

    # Filter by club
    club_id = request.values.get('club', type=int)
    if club_id:
        club = Club.get(club_id)
        if not club:
            abort(404)

        flights = flights.filter(Flight.club == club)

    # Order by date and distance
    flights = flights.order_by(Flight.date_local.desc(), Flight.olc_classic_distance)

    # Limit number of flights
    limit = request.values.get('limit', type=int, default=5)
    if not 0 < limit <= 30:
        raise BadRequest('The `limit` parameter must be between 1 and 30.')

    flights = flights.limit(limit)

    # Produce JS response
    callback = request.values.get('callback', 'onFlightsLoaded')
    return wrap(callback, render_template('widgets/flights.jinja', flights=flights))
Пример #48
0
def flights_js():
    flights = Flight.query() \
                    .filter(Flight.is_rankable())

    # Filter by user
    user_id = request.values.get('user', type=int)
    if user_id:
        user = User.get(user_id)
        if not user:
            abort(404)

        flights = flights.filter(
            or_(Flight.pilot == user, Flight.co_pilot == user))

    # Filter by club
    club_id = request.values.get('club', type=int)
    if club_id:
        club = Club.get(club_id)
        if not club:
            abort(404)

        flights = flights.filter(Flight.club == club)

    # Order by date and distance
    flights = flights.order_by(Flight.date_local.desc(),
                               Flight.olc_classic_distance)

    # Limit number of flights
    limit = request.values.get('limit', type=int, default=5)
    if not 0 < limit <= 30:
        raise BadRequest('The `limit` parameter must be between 1 and 30.')

    flights = flights.limit(limit)

    # Produce JS response
    callback = request.values.get('callback', 'onFlightsLoaded')
    return wrap(callback,
                render_template('widgets/flights.jinja', flights=flights))
Пример #49
0
def _quick_stats(user):
    result = (
        db.session.query(
            func.count("*").label("flights"),
            func.sum(Flight.olc_classic_distance).label("distance"),
            func.sum(Flight.duration).label("duration"),
        )
        .filter(Flight.pilot == user)
        .filter(Flight.date_local > (date.today() - timedelta(days=365)))
        .filter(Flight.is_rankable())
        .one()
    )

    return QuickStatsSchema().dump(result).data
Пример #50
0
def latest():
    current_user = User.get(request.user_id) if request.user_id else None

    query = db.session \
        .query(func.max(Flight.date_local).label('date')) \
        .filter(Flight.takeoff_time < datetime.utcnow()) \
        .join(Flight.igc_file) \
        .filter(Flight.is_listable(current_user))

    date_ = query.one().date
    if not date_:
        date_ = datetime.utcnow()

    return date(date_)
Пример #51
0
def _list():
    query = (Event.query().options(subqueryload("user")).options(
        subqueryload("club")).outerjoin(Event.flight).options(
            contains_eager(Event.flight)).filter(
                or_(Event.flight == None,
                    Flight.is_rankable())).order_by(Event.time.desc()))

    query = _filter_query(query, request.args)

    page = request.args.get("page", type=int, default=1)
    per_page = request.args.get("per_page", type=int, default=50)

    events = query.limit(per_page).offset((page - 1) * per_page).all()

    return jsonify(events=([convert_event(event) for event in events]))
Пример #52
0
def _get_distance_flights():
    distance_flights = []

    largest_flight = g.user.get_largest_flights() \
        .filter(Flight.is_rankable()) \
        .first()

    if largest_flight:
        distance_flights.append(
            [largest_flight.olc_classic_distance, largest_flight])

    for distance in [50000, 100000, 300000, 500000, 700000, 1000000]:
        distance_flight = _get_distance_flight(distance)
        if distance_flight is not None:
            distance_flights.append([distance, distance_flight])

    distance_flights.sort()
    return distance_flights
Пример #53
0
def _get_distance_flights():
    distance_flights = []

    largest_flight = g.user.get_largest_flights() \
        .filter(Flight.is_rankable()) \
        .first()

    if largest_flight:
        distance_flights.append([largest_flight.olc_classic_distance,
                                 largest_flight])

    for distance in [50000, 100000, 300000, 500000, 700000, 1000000]:
        distance_flight = _get_distance_flight(distance)
        if distance_flight is not None:
            distance_flights.append([distance, distance_flight])

    distance_flights.sort()
    return distance_flights
Пример #54
0
def _list():
    query = Event.query() \
        .options(subqueryload('actor')) \
        .options(subqueryload('user')) \
        .options(subqueryload('club')) \
        .outerjoin(Event.flight) \
        .options(contains_eager(Event.flight)) \
        .filter(or_(Event.flight == None, Flight.is_rankable())) \
        .order_by(Event.time.desc())

    query = _filter_query(query, request.args)

    page = request.args.get('page', type=int, default=1)
    per_page = request.args.get('per_page', type=int, default=50)

    events = query.limit(per_page).offset((page - 1) * per_page).all()

    return jsonify(events=(map(convert_event, events)))