Esempio n. 1
0
def followers(user_id):
    user = get_requested_record(User, user_id)

    # Query list of pilots that are following the selected user
    query = (Follower.query(destination=user).join("source").options(
        contains_eager("source")).options(
            subqueryload("source.club")).order_by(User.name))

    user_schema = UserSchema(only=("id", "name", "club"))
    followers = user_schema.dump([follower.source for follower in query],
                                 many=True).data

    add_current_user_follows(followers)

    return jsonify(followers=followers)
Esempio n. 2
0
def followers(user_id):
    user = get_requested_record(User, user_id)

    # Query list of pilots that are following the selected user
    query = Follower.query(destination=user) \
        .join('source') \
        .options(contains_eager('source')) \
        .options(subqueryload('source.club')) \
        .order_by(User.name)

    user_schema = UserSchema(only=('id', 'name', 'club'))
    followers = user_schema.dump([follower.source for follower in query], many=True).data

    add_current_user_follows(followers)

    return jsonify(followers=followers)
Esempio n. 3
0
def pilots():
    data = _handle_request(User, 'pilot_id')

    user_schema = UserSchema(only=('id', 'name', 'club'))

    json = []
    for pilot, count, total, rank in data['result']:
        row = {
            'rank': rank,
            'flights': count,
            'points': total,
            'user': user_schema.dump(pilot).data,
        }

        json.append(row)

    return jsonify(ranking=json, total=g.paginators['result'].count)
Esempio n. 4
0
def pilots():
    data = _handle_request_rank(User, "pilot_id")

    user_schema = UserSchema(only=("id", "name", "club"))

    json = []
    for pilot, count, total, rank in data["result"]:
        row = {
            "rank": rank,
            "flights": count,
            "points": total,
            "user": user_schema.dump(pilot).data,
        }

        json.append(row)

    return jsonify(ranking=json, total=g.paginators["result"].count)
Esempio n. 5
0
def pilots():
    data = _handle_request(User, "pilot_id")

    user_schema = UserSchema(only=("id", "name", "club"))

    json = []
    for pilot, count, total, rank in data["result"]:
        row = {
            "rank": rank,
            "flights": count,
            "points": total,
            "user": user_schema.dump(pilot).data,
        }

        json.append(row)

    return jsonify(ranking=json, total=g.paginators["result"].count)
Esempio n. 6
0
def index():
    traces = map(_get_flight_path, g.pilots)
    if not any(traces):
        traces = None

    user_schema = UserSchema()

    pilots_json = []
    for pilot in g.pilots:
        json = user_schema.dump(pilot).data
        json['color'] = pilot.color
        pilots_json.append(json)

    return render_template('tracking/map.jinja',
                           pilots=g.pilots,
                           pilots_json=pilots_json,
                           traces=traces)
Esempio n. 7
0
def following(user_id):
    user = get_requested_record(User, user_id)

    # Query list of pilots that are following the selected user
    query = Follower.query(source=user) \
        .join('destination') \
        .options(contains_eager('destination')) \
        .options(subqueryload('destination.club')) \
        .order_by(User.name)

    user_schema = UserSchema(only=('id', 'name', 'club'))

    following = user_schema.dump([follower.destination for follower in query],
                                 many=True).data

    add_current_user_follows(following)

    return jsonify(following=following)
Esempio n. 8
0
def read(user_ids):
    pilots = get_requested_record_list(User, user_ids, joinedload=[User.club])

    color_gen = color.generator()
    for pilot in pilots:
        pilot.color = next(color_gen)

    traces = list(map(_get_flight_path, pilots))
    if not any(traces):
        traces = None

    user_schema = UserSchema()

    pilots_json = []
    for pilot in pilots:
        json = user_schema.dump(pilot).data
        json["color"] = pilot.color
        pilots_json.append(json)

    flights = []
    if traces:
        for pilot, trace in zip(pilots, traces):
            if trace:
                flights.append(
                    {
                        "sfid": pilot.id,
                        "points": trace["points"],
                        "barogram_t": trace["barogram_t"],
                        "barogram_h": trace["barogram_h"],
                        "enl": trace["enl"],
                        "contests": None,
                        "elevations_t": trace["barogram_t"],
                        "elevations_h": trace["elevations"],
                        "geoid": trace["geoid"],
                        "additional": {
                            "competition_id": pilot.tracking_callsign
                            or pilot.initials(),
                            "color": pilot.color,
                        },
                    }
                )

    return jsonify(flights=flights, pilots=pilots_json)
Esempio n. 9
0
def read(user_ids):
    pilots = get_requested_record_list(User, user_ids, joinedload=[User.club])

    color_gen = color.generator()
    for pilot in pilots:
        pilot.color = color_gen.next()

    traces = map(_get_flight_path, pilots)
    if not any(traces):
        traces = None

    user_schema = UserSchema()

    pilots_json = []
    for pilot in pilots:
        json = user_schema.dump(pilot).data
        json['color'] = pilot.color
        pilots_json.append(json)

    flights = []
    if traces:
        for pilot, trace in zip(pilots, traces):
            if trace:
                flights.append({
                    'sfid': pilot.id,
                    'points': trace['points'],
                    'barogram_t': trace['barogram_t'],
                    'barogram_h': trace['barogram_h'],
                    'enl': trace['enl'],
                    'contests': None,
                    'elevations_t': trace['barogram_t'],
                    'elevations_h': trace['elevations'],
                    'geoid': trace['geoid'],
                    'additional': {
                        'competition_id':
                        pilot.tracking_callsign or pilot.initials(),
                        'color':
                        pilot.color,
                    },
                })

    return jsonify(flights=flights, pilots=pilots_json)
Esempio n. 10
0
def read(user_ids):
    pilots = get_requested_record_list(User, user_ids, joinedload=[User.club])

    color_gen = color.generator()
    for pilot in pilots:
        pilot.color = next(color_gen)

    traces = list(map(_get_flight_path, pilots))
    if not any(traces):
        traces = None

    user_schema = UserSchema()

    pilots_json = []
    for pilot in pilots:
        json = user_schema.dump(pilot).data
        json["color"] = pilot.color
        pilots_json.append(json)

    flights = []
    if traces:
        for pilot, trace in zip(pilots, traces):
            if trace:
                flights.append({
                    "sfid": pilot.id,
                    "points": trace["points"],
                    "barogram_t": trace["barogram_t"],
                    "barogram_h": trace["barogram_h"],
                    "enl": trace["enl"],
                    "contests": None,
                    "elevations_t": trace["barogram_t"],
                    "elevations_h": trace["elevations"],
                    "geoid": trace["geoid"],
                    "additional": {
                        "competition_id":
                        pilot.tracking_callsign or pilot.initials(),
                        "color":
                        pilot.color,
                    },
                })

    return jsonify(flights=flights, pilots=pilots_json)
Esempio n. 11
0
def pilots():
    data = _handle_request(User, 'pilot_id')

    if 'application/json' in request.headers.get('Accept', ''):
        user_schema = UserSchema(only=('id', 'name', 'club'))

        json = []
        for pilot, count, total, rank in data['result']:
            row = {
                'rank': rank,
                'flights': count,
                'points': total,
                'user': user_schema.dump(pilot).data,
            }

            json.append(row)

        return jsonify(ranking=json, total=g.paginators['result'].count)

    return render_template('ember-page.jinja', active_page='ranking')
Esempio n. 12
0
def pilots():
    data = _handle_request(User, 'pilot_id')

    if 'application/json' in request.headers.get('Accept', ''):
        user_schema = UserSchema(only=('id', 'name', 'club'))

        json = []
        for pilot, count, total, rank in data['result']:
            row = {
                'rank': rank,
                'flights': count,
                'points': total,
                'user': user_schema.dump(pilot).data,
            }

            json.append(row)

        return jsonify(ranking=json, total=g.paginators['result'].count)

    return render_template('ember-page.jinja', active_page='ranking')
Esempio n. 13
0
def following(user_id):
    user = get_requested_record(User, user_id)

    # Query list of pilots that are following the selected user
    query = (
        Follower.query(source=user)
        .join("destination")
        .options(contains_eager("destination"))
        .options(subqueryload("destination.club"))
        .order_by(User.name)
    )

    user_schema = UserSchema(only=("id", "name", "club"))

    following = user_schema.dump(
        [follower.destination for follower in query], many=True
    ).data

    add_current_user_follows(following)

    return jsonify(following=following)
Esempio n. 14
0
def _list():
    users = User.query().options(joinedload(User.club)).order_by(
        func.lower(User.name))

    fields = ["id", "name"]

    if "club" in request.args:
        users = users.filter_by(club_id=request.args.get("club"))
    else:
        fields.append("club")

    return jsonify(users=UserSchema(only=fields).dump(users, many=True).data)
Esempio n. 15
0
def read(user_ids):
    pilots = get_requested_record_list(User, user_ids, joinedload=[User.club])

    color_gen = color.generator()
    for pilot in pilots:
        pilot.color = color_gen.next()

    traces = map(_get_flight_path, pilots)
    if not any(traces):
        traces = None

    user_schema = UserSchema()

    pilots_json = []
    for pilot in pilots:
        json = user_schema.dump(pilot).data
        json['color'] = pilot.color
        pilots_json.append(json)

    flights = []
    if traces:
        for pilot, trace in zip(pilots, traces):
            if trace:
                flights.append({
                    'sfid': pilot.id,
                    'points': trace['points'],
                    'barogram_t': trace['barogram_t'],
                    'barogram_h': trace['barogram_h'],
                    'enl': trace['enl'],
                    'contests': None,
                    'elevations_t': trace['barogram_t'],
                    'elevations_h': trace['elevations'],
                    'geoid': trace['geoid'],
                    'additional': {
                        'competition_id': pilot.tracking_callsign or pilot.initials(),
                        'color': pilot.color,
                    },
                })

    return jsonify(flights=flights, pilots=pilots_json)
Esempio n. 16
0
def _list():
    users = User.query() \
        .options(joinedload(User.club)) \
        .order_by(func.lower(User.name))

    fields = ['id', 'name']

    if 'club' in request.args:
        users = users.filter_by(club_id=request.args.get('club'))
    else:
        fields.append('club')

    return jsonify(users=UserSchema(only=fields).dump(users, many=True).data)
Esempio n. 17
0
def index():
    if 'application/json' not in request.headers.get('Accept', ''):
        return render_template('ember-page.jinja', active_page='settings')

    users = User.query() \
        .options(joinedload(User.club)) \
        .order_by(func.lower(User.name))

    fields = ['id', 'name']

    if 'club' in request.args:
        users = users.filter_by(club_id=request.args.get('club'))
    else:
        fields.append('club')

    return jsonify(users=UserSchema(only=fields).dump(users, many=True).data)
Esempio n. 18
0
def read(user_id):
    user = get_requested_record(User, user_id)

    user_schema = CurrentUserSchema(
    ) if user_id == request.user_id else UserSchema()
    user_json = user_schema.dump(user).data

    if request.user_id:
        current_user = User.get(request.user_id)
        user_json["followed"] = current_user.follows(user)

    if "extended" in request.args:
        user_json["distanceFlights"] = _distance_flights(user)
        user_json["stats"] = _quick_stats(user)
        user_json["takeoffLocations"] = _get_takeoff_locations(user)

    mark_user_notifications_read(user)

    return jsonify(user_json)
Esempio n. 19
0
def index():
    if 'application/json' in request.headers.get('Accept', ''):
        user_schema = CurrentUserSchema(
        ) if g.user == g.current_user else UserSchema()
        user = user_schema.dump(g.user).data

        if g.current_user:
            user['followed'] = g.current_user.follows(g.user)

        if 'extended' in request.args:
            user['distanceFlights'] = _distance_flights(g.user)
            user['stats'] = _quick_stats()
            user['takeoffLocations'] = _get_takeoff_locations()

        return jsonify(**user)

    mark_user_notifications_read(g.user)

    return render_template('ember-page.jinja',
                           openlayers=True,
                           active_page='settings')
Esempio n. 20
0
def new_post():
    json = request.get_json()
    if json is None:
        return jsonify(error="invalid-request"), 400

    try:
        data = (CurrentUserSchema(only=("email", "firstName", "lastName",
                                        "password")).load(json).data)
    except ValidationError as e:
        return jsonify(error="validation-failed", fields=e.messages), 422

    user = User(**data)

    user.created_ip = request.remote_addr
    db.session.add(user)

    create_new_user_event(user)

    db.session.commit()

    return jsonify(user=UserSchema().dump(user).data)
Esempio n. 21
0
def _create_list(
    date=None,
    pilot=None,
    club=None,
    airport=None,
    pinned=None,
    filter=None,
    default_sorting_column="score",
    default_sorting_order="desc",
):

    pilot_alias = aliased(User, name="pilot")
    owner_alias = aliased(User, name="owner")

    subq = (db.session.query(FlightComment.flight_id,
                             func.count("*").label("count")).group_by(
                                 FlightComment.flight_id).subquery())

    current_user = User.get(request.user_id) if request.user_id else None

    flights = (db.session.query(Flight, subq.c.count).filter(
        Flight.is_listable(current_user)).join(Flight.igc_file).options(
            contains_eager(Flight.igc_file)).join(
                owner_alias, IGCFile.owner).options(
                    contains_eager(Flight.igc_file,
                                   IGCFile.owner,
                                   alias=owner_alias)).outerjoin(
                                       pilot_alias, Flight.pilot).options(
                                           contains_eager(Flight.pilot,
                                                          alias=pilot_alias)).
               options(joinedload(Flight.co_pilot)).outerjoin(
                   Flight.club).options(contains_eager(Flight.club)).outerjoin(
                       Flight.takeoff_airport).options(
                           contains_eager(Flight.takeoff_airport)).outerjoin(
                               Flight.model).options(
                                   contains_eager(Flight.model)).outerjoin(
                                       (subq, Flight.comments)))

    if date:
        flights = flights.filter(Flight.date_local == date)

    if pilot:
        flights = flights.filter(
            or_(Flight.pilot == pilot, Flight.co_pilot == pilot))
    if club:
        flights = flights.filter(Flight.club == club)

    if airport:
        flights = flights.filter(Flight.takeoff_airport == airport)

    if pinned:
        flights = flights.filter(Flight.id.in_(pinned))

    if filter is not None:
        flights = flights.filter(filter)

    valid_columns = {
        "date": getattr(Flight, "date_local"),
        "score": getattr(Flight, "index_score"),
        "pilot": getattr(pilot_alias, "name"),
        "distance": getattr(Flight, "olc_classic_distance"),
        "airport": getattr(Airport, "name"),
        "club": getattr(Club, "name"),
        "aircraft": getattr(AircraftModel, "name"),
        "time": getattr(Flight, "takeoff_time"),
    }

    flights_count = flights.count()

    flights = Sorter.sort(
        flights,
        "flights",
        default_sorting_column,
        valid_columns=valid_columns,
        default_order=default_sorting_order,
    )

    flights = flights.order_by(Flight.index_score.desc())

    flights = Pager.paginate(
        flights,
        "flights",
        items_per_page=int(
            current_app.config.get("SKYLINES_LISTS_DISPLAY_LENGTH", 50)),
    )

    flight_schema = FlightSchema()
    flights_json = []
    for f, num_comments in flights:
        flight = flight_schema.dump(f).data
        flight["private"] = not f.is_rankable()
        flight["numComments"] = num_comments
        flights_json.append(flight)

    json = dict(flights=flights_json, count=flights_count)

    if date:
        json["date"] = date.isoformat()

    if pilot:
        user_schema = UserSchema(only=("id", "name"))
        json["pilot"] = user_schema.dump(pilot).data

    if club:
        club_schema = ClubSchema(only=("id", "name"))
        json["club"] = club_schema.dump(club).data

    if airport:
        airport_schema = AirportSchema(only=("id", "name", "countryCode"))
        json["airport"] = airport_schema.dump(airport).data

    return jsonify(json)
Esempio n. 22
0
def index_post(form):
    user = g.current_user

    pilot_id = form.pilot.data if form.pilot.data != 0 else None
    pilot = pilot_id and User.get(int(pilot_id))
    pilot_id = pilot and pilot.id

    club_id = (pilot and pilot.club_id) or user.club_id

    results = []
    success = False

    prefix = 0
    for name, f in iterate_upload_files(form.file.raw_data):
        prefix += 1
        filename = files.sanitise_filename(name)
        filename = files.add_file(filename, f)

        # check if the file already exists
        with files.open_file(filename) as f:
            md5 = file_md5(f)
            other = Flight.by_md5(md5)
            if other:
                files.delete_file(filename)
                results.append(
                    UploadResult.for_duplicate(name, other, str(prefix)))
                continue

        igc_file = IGCFile()
        igc_file.owner = user
        igc_file.filename = filename
        igc_file.md5 = md5
        igc_file.update_igc_headers()

        if igc_file.date_utc is None:
            files.delete_file(filename)
            results.append(UploadResult.for_missing_date(name, str(prefix)))
            continue

        flight = Flight()
        flight.pilot_id = pilot_id
        flight.pilot_name = form.pilot_name.data if form.pilot_name.data else None
        flight.club_id = club_id
        flight.igc_file = igc_file

        flight.model_id = igc_file.guess_model()

        if igc_file.registration:
            flight.registration = igc_file.registration
        else:
            flight.registration = igc_file.guess_registration()

        flight.competition_id = igc_file.competition_id

        fp = flight_path(flight.igc_file, add_elevation=True, max_points=None)

        analyzed = False
        try:
            analyzed = analyse_flight(flight, fp=fp)
        except:
            current_app.logger.exception(
                'analyse_flight() raised an exception')

        if not analyzed:
            files.delete_file(filename)
            results.append(UploadResult.for_parser_error(name, str(prefix)))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            results.append(UploadResult.for_future_flight(name, str(prefix)))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        flight.privacy_level = Flight.PrivacyLevel.PRIVATE

        trace = _encode_flight_path(fp, qnh=flight.qnh)
        infringements = get_airspace_infringements(fp, qnh=flight.qnh)

        db.session.add(igc_file)
        db.session.add(flight)

        # flush data to make sure we don't get duplicate files from ZIP files
        db.session.flush()

        # Store data in cache for image creation
        cache_key = hashlib.sha1(str(flight.id) + '_' +
                                 str(user.id)).hexdigest()

        current_app.cache.set('upload_airspace_infringements_' + cache_key,
                              infringements,
                              timeout=15 * 60)
        current_app.cache.set('upload_airspace_flight_path_' + cache_key,
                              fp,
                              timeout=15 * 60)

        airspace = db.session.query(Airspace) \
                             .filter(Airspace.id.in_(infringements.keys())) \
                             .all()

        results.append(
            UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix),
                         trace, airspace, cache_key))

        create_flight_notifications(flight)

        success = True

    db.session.commit()

    if success:
        flash(
            _('Please click "Publish Flight(s)" at the bottom to confirm our automatic analysis.'
              ))

    results_json = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if g.current_user.club_id:
        member_schema = UserSchema(only=('id', 'name'))

        club_members = User.query(club_id=g.current_user.club_id) \
            .order_by(func.lower(User.name)) \
            .filter(User.id != g.current_user.id)

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = AircraftModel.query() \
        .order_by(AircraftModel.kind) \
        .order_by(AircraftModel.name) \
        .all()

    aircraft_models = AircraftModelSchema().dump(aircraft_models,
                                                 many=True).data

    return render_template('upload/result.jinja',
                           num_flights=prefix,
                           results=results,
                           success=success,
                           results_json=results_json,
                           club_members=club_members,
                           aircraft_models=aircraft_models)
Esempio n. 23
0
def schema():
    return UserSchema()
Esempio n. 24
0
def index_post():
    current_user = User.get(request.user_id)

    try:
        data = FlightUploadSchema().load(request.form).data
    except ValidationError as e:
        return jsonify(error="validation-failed", fields=e.messages), 422

    pilot_id = data.get("pilot_id")
    if pilot_id:
        pilot = User.get(pilot_id)
        if not pilot:
            return jsonify(error="unknown-pilot"), 422
    else:
        pilot = None

    club_id = (pilot and pilot.club_id) or current_user.club_id

    results = []
    weglide_uploads = []

    _files = request.files.getlist("files")

    prefix = 0
    for name, f in iterate_upload_files(_files):
        prefix += 1
        filename = files.sanitise_filename(name)
        filename = files.add_file(filename, f)

        # check if the file already exists
        with files.open_file(filename) as f:
            md5 = file_md5(f)
            other = Flight.by_md5(md5)
            if other:
                files.delete_file(filename)
                results.append(UploadResult.for_duplicate(name, other, str(prefix)))
                continue

        igc_file = IGCFile()
        igc_file.owner = current_user
        igc_file.filename = filename
        igc_file.md5 = md5
        igc_file.update_igc_headers()

        if igc_file.date_utc is None:
            files.delete_file(filename)
            results.append(UploadResult.for_missing_date(name, str(prefix)))
            continue

        flight = Flight()
        flight.pilot_id = pilot_id
        flight.pilot_name = data.get("pilot_name")
        flight.club_id = club_id
        flight.igc_file = igc_file

        flight.model_id = igc_file.guess_model()

        if igc_file.registration:
            flight.registration = igc_file.registration
        else:
            flight.registration = igc_file.guess_registration()

        flight.competition_id = igc_file.competition_id

        fp = flight_path(flight.igc_file, add_elevation=True, max_points=None)

        analyzed = False
        try:
            analyzed = analyse_flight(flight, fp=fp)
        except:
            current_app.logger.exception("analyse_flight() raised an exception")

        if not analyzed:
            files.delete_file(filename)
            results.append(UploadResult.for_parser_error(name, str(prefix)))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            results.append(UploadResult.for_future_flight(name, str(prefix)))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        flight.privacy_level = Flight.PrivacyLevel.PRIVATE

        trace = _encode_flight_path(fp, qnh=flight.qnh)
        infringements = get_airspace_infringements(fp, qnh=flight.qnh)

        db.session.add(igc_file)
        db.session.add(flight)

        # flush data to make sure we don't get duplicate files from ZIP files
        db.session.flush()

        # Queue WeGlide upload if requested
        weglide_user_id = data.get("weglideUserId")
        weglide_birthday = data.get("weglideBirthday")
        if weglide_user_id and weglide_birthday:
            # Save `upload_to_weglide` task parameters for later. We can't start
            # the task directly here, because the DB transaction has not been
            # committed at this point.
            weglide_uploads.append(
                (igc_file.id, weglide_user_id, weglide_birthday.isoformat())
            )

            # Update `weglide_status` in the database
            igc_file.weglide_status = 1
            db.session.flush()

        # Store data in cache for image creation
        cache_key = hashlib.sha1(
            (to_unicode(flight.id) + u"_" + to_unicode(current_user.id)).encode("utf-8")
        ).hexdigest()

        cache.set(
            "upload_airspace_infringements_" + cache_key, infringements, timeout=15 * 60
        )
        cache.set("upload_airspace_flight_path_" + cache_key, fp, timeout=15 * 60)

        airspace = (
            db.session.query(Airspace)
            .filter(Airspace.id.in_(infringements.keys()))
            .all()
        )

        results.append(
            UploadResult(
                name,
                flight,
                UploadStatus.SUCCESS,
                str(prefix),
                trace,
                airspace,
                cache_key,
            )
        )

        create_flight_notifications(flight)

    db.session.commit()

    # Schedule the deferred WeGlide upload tasks from above
    for weglide_upload in weglide_uploads:
        tasks.upload_to_weglide.delay(*weglide_upload)

    results = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if current_user.club_id:
        member_schema = UserSchema(only=("id", "name"))

        club_members = (
            User.query(club_id=current_user.club_id)
            .order_by(func.lower(User.name))
            .filter(User.id != current_user.id)
        )

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = (
        AircraftModel.query()
        .order_by(AircraftModel.kind)
        .order_by(AircraftModel.name)
        .all()
    )

    aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data

    return jsonify(
        results=results, club_members=club_members, aircraft_models=aircraft_models
    )
Esempio n. 25
0
def callsign_schema():
    return UserSchema(only=("trackingCallsign",))
Esempio n. 26
0
        return jsonify(error='validation-failed', fields=e.messages), 422

    user = User(**data)

    user.created_ip = request.remote_addr
    db.session.add(user)

    create_new_user_event(user)

    db.session.commit()

    flash(
        _('Welcome to SkyLines, %(user)s! You can now log in and share your flights with the world!',
          user=user))

    return jsonify(user=UserSchema().dump(user).data)


@users_blueprint.route('/recover')
def recover():
    return render_template('ember-page.jinja', active_page='settings')


@users_blueprint.route('/recover', methods=['POST'])
def recover_post():
    json = request.get_json()
    if json is None:
        return jsonify(error='invalid-request'), 400

    if 'recoveryKey' in json:
        return recover_step2_post(json)
Esempio n. 27
0
def _create_list(
    date=None,
    pilot=None,
    club=None,
    airport=None,
    pinned=None,
    filter=None,
    default_sorting_column="score",
    default_sorting_order="desc",
):

    pilot_alias = aliased(User, name="pilot")
    owner_alias = aliased(User, name="owner")

    subq = (
        db.session.query(FlightComment.flight_id, func.count("*").label("count"))
        .group_by(FlightComment.flight_id)
        .subquery()
    )

    current_user = User.get(request.user_id) if request.user_id else None

    flights = (
        db.session.query(Flight, subq.c.count)
        .filter(Flight.is_listable(current_user))
        .join(Flight.igc_file)
        .options(contains_eager(Flight.igc_file))
        .join(owner_alias, IGCFile.owner)
        .options(contains_eager(Flight.igc_file, IGCFile.owner, alias=owner_alias))
        .outerjoin(pilot_alias, Flight.pilot)
        .options(contains_eager(Flight.pilot, alias=pilot_alias))
        .options(joinedload(Flight.co_pilot))
        .outerjoin(Flight.club)
        .options(contains_eager(Flight.club))
        .outerjoin(Flight.takeoff_airport)
        .options(contains_eager(Flight.takeoff_airport))
        .outerjoin(Flight.model)
        .options(contains_eager(Flight.model))
        .outerjoin((subq, Flight.comments))
    )

    if date:
        flights = flights.filter(Flight.date_local == date)

    if pilot:
        flights = flights.filter(or_(Flight.pilot == pilot, Flight.co_pilot == pilot))
    if club:
        flights = flights.filter(Flight.club == club)

    if airport:
        flights = flights.filter(Flight.takeoff_airport == airport)

    if pinned:
        flights = flights.filter(Flight.id.in_(pinned))

    if filter is not None:
        flights = flights.filter(filter)

    valid_columns = {
        "date": getattr(Flight, "date_local"),
        "score": getattr(Flight, "index_score"),
        "pilot": getattr(pilot_alias, "name"),
        "distance": getattr(Flight, "olc_classic_distance"),
        "airport": getattr(Airport, "name"),
        "club": getattr(Club, "name"),
        "aircraft": getattr(AircraftModel, "name"),
        "time": getattr(Flight, "takeoff_time"),
    }

    flights_count = flights.count()

    flights = Sorter.sort(
        flights, "flights", default_sorting_column, valid_columns=valid_columns, default_order=default_sorting_order
    )

    flights = flights.order_by(Flight.index_score.desc())

    flights = Pager.paginate(
        flights, "flights", items_per_page=int(current_app.config.get("SKYLINES_LISTS_DISPLAY_LENGTH", 50))
    )

    flight_schema = FlightSchema()
    flights_json = []
    for f, num_comments in flights:
        flight = flight_schema.dump(f).data
        flight["private"] = not f.is_rankable()
        flight["numComments"] = num_comments
        flights_json.append(flight)

    json = dict(flights=flights_json, count=flights_count)

    if date:
        json["date"] = date.isoformat()

    if pilot:
        user_schema = UserSchema(only=("id", "name"))
        json["pilot"] = user_schema.dump(pilot).data

    if club:
        club_schema = ClubSchema(only=("id", "name"))
        json["club"] = club_schema.dump(club).data

    if airport:
        airport_schema = AirportSchema(only=("id", "name", "countryCode"))
        json["airport"] = airport_schema.dump(airport).data

    return jsonify(json)
Esempio n. 28
0
def _create_list(date=None, pilot=None, club=None, airport=None,
                 pinned=None, filter=None,
                 default_sorting_column='score', default_sorting_order='desc'):

    pilot_alias = aliased(User, name='pilot')
    owner_alias = aliased(User, name='owner')

    subq = db.session \
        .query(FlightComment.flight_id, func.count('*').label('count')) \
        .group_by(FlightComment.flight_id).subquery()

    current_user = User.get(request.user_id) if request.user_id else None

    flights = db.session.query(Flight, subq.c.count) \
        .filter(Flight.is_listable(current_user)) \
        .join(Flight.igc_file) \
        .options(contains_eager(Flight.igc_file)) \
        .join(owner_alias, IGCFile.owner) \
        .options(contains_eager(Flight.igc_file, IGCFile.owner, alias=owner_alias)) \
        .outerjoin(pilot_alias, Flight.pilot) \
        .options(contains_eager(Flight.pilot, alias=pilot_alias)) \
        .options(joinedload(Flight.co_pilot)) \
        .outerjoin(Flight.club) \
        .options(contains_eager(Flight.club)) \
        .outerjoin(Flight.takeoff_airport) \
        .options(contains_eager(Flight.takeoff_airport)) \
        .outerjoin(Flight.model) \
        .options(contains_eager(Flight.model)) \
        .outerjoin((subq, Flight.comments))

    if date:
        flights = flights.filter(Flight.date_local == date)

    if pilot:
        flights = flights.filter(or_(Flight.pilot == pilot,
                                     Flight.co_pilot == pilot))
    if club:
        flights = flights.filter(Flight.club == club)

    if airport:
        flights = flights.filter(Flight.takeoff_airport == airport)

    if pinned:
        flights = flights.filter(Flight.id.in_(pinned))

    if filter is not None:
        flights = flights.filter(filter)

    valid_columns = {
        'date': getattr(Flight, 'date_local'),
        'score': getattr(Flight, 'index_score'),
        'pilot': getattr(pilot_alias, 'name'),
        'distance': getattr(Flight, 'olc_classic_distance'),
        'airport': getattr(Airport, 'name'),
        'club': getattr(Club, 'name'),
        'aircraft': getattr(AircraftModel, 'name'),
        'time': getattr(Flight, 'takeoff_time'),
    }

    flights_count = flights.count()

    flights = Sorter.sort(flights, 'flights', default_sorting_column,
                          valid_columns=valid_columns,
                          default_order=default_sorting_order)

    flights = flights.order_by(Flight.index_score.desc())

    flights = Pager.paginate(flights, 'flights',
                             items_per_page=int(current_app.config.get('SKYLINES_LISTS_DISPLAY_LENGTH', 50)))

    flight_schema = FlightSchema()
    flights_json = []
    for f, num_comments in flights:
        flight = flight_schema.dump(f).data
        flight['private'] = not f.is_rankable()
        flight['numComments'] = num_comments
        flights_json.append(flight)

    json = dict(flights=flights_json, count=flights_count)

    if date:
        json['date'] = date.isoformat()

    if pilot:
        user_schema = UserSchema(only=('id', 'name'))
        json['pilot'] = user_schema.dump(pilot).data

    if club:
        club_schema = ClubSchema(only=('id', 'name'))
        json['club'] = club_schema.dump(club).data

    if airport:
        airport_schema = AirportSchema(only=('id', 'name', 'countryCode'))
        json['airport'] = airport_schema.dump(airport).data

    return jsonify(json)
Esempio n. 29
0
                             .filter(Airspace.id.in_(infringements.keys())) \
                             .all()

        results.append(
            UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix),
                         trace, airspace, cache_key))

        create_flight_notifications(flight)

    db.session.commit()

    results = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if current_user.club_id:
        member_schema = UserSchema(only=('id', 'name'))

        club_members = User.query(club_id=current_user.club_id) \
            .order_by(func.lower(User.name)) \
            .filter(User.id != current_user.id)

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = AircraftModel.query() \
        .order_by(AircraftModel.kind) \
        .order_by(AircraftModel.name) \
        .all()

    aircraft_models = AircraftModelSchema().dump(aircraft_models,
                                                 many=True).data
Esempio n. 30
0
def index_post(form):
    user = g.current_user

    pilot_id = form.pilot.data if form.pilot.data != 0 else None
    pilot = pilot_id and User.get(int(pilot_id))
    pilot_id = pilot and pilot.id

    club_id = (pilot and pilot.club_id) or user.club_id

    results = []
    success = False

    prefix = 0
    for name, f in iterate_upload_files(form.file.raw_data):
        prefix += 1
        filename = files.sanitise_filename(name)
        filename = files.add_file(filename, f)

        # check if the file already exists
        with files.open_file(filename) as f:
            md5 = file_md5(f)
            other = Flight.by_md5(md5)
            if other:
                files.delete_file(filename)
                results.append(UploadResult.for_duplicate(name, other, str(prefix)))
                continue

        igc_file = IGCFile()
        igc_file.owner = user
        igc_file.filename = filename
        igc_file.md5 = md5
        igc_file.update_igc_headers()

        if igc_file.date_utc is None:
            files.delete_file(filename)
            results.append(UploadResult.for_missing_date(name, str(prefix)))
            continue

        flight = Flight()
        flight.pilot_id = pilot_id
        flight.pilot_name = form.pilot_name.data if form.pilot_name.data else None
        flight.club_id = club_id
        flight.igc_file = igc_file

        flight.model_id = igc_file.guess_model()

        if igc_file.registration:
            flight.registration = igc_file.registration
        else:
            flight.registration = igc_file.guess_registration()

        flight.competition_id = igc_file.competition_id

        fp = flight_path(flight.igc_file, add_elevation=True, max_points=None)

        analyzed = False
        try:
            analyzed = analyse_flight(flight, fp=fp)
        except:
            current_app.logger.exception('analyse_flight() raised an exception')

        if not analyzed:
            files.delete_file(filename)
            results.append(UploadResult.for_parser_error(name, str(prefix)))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            results.append(UploadResult.for_future_flight(name, str(prefix)))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        flight.privacy_level = Flight.PrivacyLevel.PRIVATE

        trace = _encode_flight_path(fp, qnh=flight.qnh)
        infringements = get_airspace_infringements(fp, qnh=flight.qnh)

        db.session.add(igc_file)
        db.session.add(flight)

        # flush data to make sure we don't get duplicate files from ZIP files
        db.session.flush()

        # Store data in cache for image creation
        cache_key = hashlib.sha1(str(flight.id) + '_' + str(user.id)).hexdigest()

        current_app.cache.set('upload_airspace_infringements_' + cache_key, infringements, timeout=15 * 60)
        current_app.cache.set('upload_airspace_flight_path_' + cache_key, fp, timeout=15 * 60)

        airspace = db.session.query(Airspace) \
                             .filter(Airspace.id.in_(infringements.keys())) \
                             .all()

        results.append(UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key))

        create_flight_notifications(flight)

        success = True

    db.session.commit()

    if success:
        flash(_('Please click "Publish Flight(s)" at the bottom to confirm our automatic analysis.'))

    results_json = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if g.current_user.club_id:
        member_schema = UserSchema(only=('id', 'name'))

        club_members = User.query(club_id=g.current_user.club_id) \
            .order_by(func.lower(User.name)) \
            .filter(User.id != g.current_user.id)

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = AircraftModel.query() \
        .order_by(AircraftModel.kind) \
        .order_by(AircraftModel.name) \
        .all()

    aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data

    return render_template(
        'upload/result.jinja', num_flights=prefix, results=results, success=success,
        results_json=results_json, club_members=club_members, aircraft_models=aircraft_models)
Esempio n. 31
0
def partial_schema():
    return UserSchema(partial=True)
Esempio n. 32
0
        airspace = db.session.query(Airspace) \
                             .filter(Airspace.id.in_(infringements.keys())) \
                             .all()

        results.append(UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key))

        create_flight_notifications(flight)

    db.session.commit()

    results = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if current_user.club_id:
        member_schema = UserSchema(only=('id', 'name'))

        club_members = User.query(club_id=current_user.club_id) \
            .order_by(func.lower(User.name)) \
            .filter(User.id != current_user.id)

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = AircraftModel.query() \
        .order_by(AircraftModel.kind) \
        .order_by(AircraftModel.name) \
        .all()

    aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data

    return jsonify(results=results, club_members=club_members, aircraft_models=aircraft_models)
Esempio n. 33
0
def _create_list(date=None,
                 pilot=None,
                 club=None,
                 airport=None,
                 pinned=None,
                 filter=None,
                 default_sorting_column='score',
                 default_sorting_order='desc'):

    pilot_alias = aliased(User, name='pilot')
    owner_alias = aliased(User, name='owner')

    subq = db.session \
        .query(FlightComment.flight_id, func.count('*').label('count')) \
        .group_by(FlightComment.flight_id).subquery()

    current_user = User.get(request.user_id) if request.user_id else None

    flights = db.session.query(Flight, subq.c.count) \
        .filter(Flight.is_listable(current_user)) \
        .join(Flight.igc_file) \
        .options(contains_eager(Flight.igc_file)) \
        .join(owner_alias, IGCFile.owner) \
        .options(contains_eager(Flight.igc_file, IGCFile.owner, alias=owner_alias)) \
        .outerjoin(pilot_alias, Flight.pilot) \
        .options(contains_eager(Flight.pilot, alias=pilot_alias)) \
        .options(joinedload(Flight.co_pilot)) \
        .outerjoin(Flight.club) \
        .options(contains_eager(Flight.club)) \
        .outerjoin(Flight.takeoff_airport) \
        .options(contains_eager(Flight.takeoff_airport)) \
        .outerjoin(Flight.model) \
        .options(contains_eager(Flight.model)) \
        .outerjoin((subq, Flight.comments))

    if date:
        flights = flights.filter(Flight.date_local == date)

    if pilot:
        flights = flights.filter(
            or_(Flight.pilot == pilot, Flight.co_pilot == pilot))
    if club:
        flights = flights.filter(Flight.club == club)

    if airport:
        flights = flights.filter(Flight.takeoff_airport == airport)

    if pinned:
        flights = flights.filter(Flight.id.in_(pinned))

    if filter is not None:
        flights = flights.filter(filter)

    valid_columns = {
        'date': getattr(Flight, 'date_local'),
        'score': getattr(Flight, 'index_score'),
        'pilot': getattr(pilot_alias, 'name'),
        'distance': getattr(Flight, 'olc_classic_distance'),
        'airport': getattr(Airport, 'name'),
        'club': getattr(Club, 'name'),
        'aircraft': getattr(AircraftModel, 'name'),
        'time': getattr(Flight, 'takeoff_time'),
    }

    flights_count = flights.count()

    flights = Sorter.sort(flights,
                          'flights',
                          default_sorting_column,
                          valid_columns=valid_columns,
                          default_order=default_sorting_order)

    flights = flights.order_by(Flight.index_score.desc())

    flights = Pager.paginate(flights,
                             'flights',
                             items_per_page=int(
                                 current_app.config.get(
                                     'SKYLINES_LISTS_DISPLAY_LENGTH', 50)))

    flight_schema = FlightSchema()
    flights_json = []
    for f, num_comments in flights:
        flight = flight_schema.dump(f).data
        flight['private'] = not f.is_rankable()
        flight['numComments'] = num_comments
        flights_json.append(flight)

    json = dict(flights=flights_json, count=flights_count)

    if date:
        json['date'] = date.isoformat()

    if pilot:
        user_schema = UserSchema(only=('id', 'name'))
        json['pilot'] = user_schema.dump(pilot).data

    if club:
        club_schema = ClubSchema(only=('id', 'name'))
        json['club'] = club_schema.dump(club).data

    if airport:
        airport_schema = AirportSchema(only=('id', 'name', 'countryCode'))
        json['airport'] = airport_schema.dump(airport).data

    return jsonify(json)
Esempio n. 34
0
def delay_schema():
    return UserSchema(only=("trackingDelay",))
Esempio n. 35
0
def index_post():
    current_user = User.get(request.user_id)

    form = request.form

    if form.get("pilotId") == u"":
        form = form.copy()
        form.pop("pilotId")

    try:
        data = FlightSchema(only=("pilotId", "pilotName")).load(form).data
    except ValidationError as e:
        return jsonify(error="validation-failed", fields=e.messages), 422

    pilot_id = data.get("pilot_id")
    pilot = pilot_id and User.get(pilot_id)
    pilot_id = pilot and pilot.id

    club_id = (pilot and pilot.club_id) or current_user.club_id

    results = []

    _files = request.files.getlist("files")

    prefix = 0
    for name, f in iterate_upload_files(_files):
        prefix += 1
        filename = files.sanitise_filename(name)
        filename = files.add_file(filename, f)

        # check if the file already exists
        with files.open_file(filename) as f:
            md5 = file_md5(f)
            other = Flight.by_md5(md5)
            if other:
                files.delete_file(filename)
                results.append(UploadResult.for_duplicate(name, other, str(prefix)))
                continue

        igc_file = IGCFile()
        igc_file.owner = current_user
        igc_file.filename = filename
        igc_file.md5 = md5
        igc_file.update_igc_headers()

        if igc_file.date_utc is None:
            files.delete_file(filename)
            results.append(UploadResult.for_missing_date(name, str(prefix)))
            continue

        flight = Flight()
        flight.pilot_id = pilot_id
        flight.pilot_name = data.get("pilot_name")
        flight.club_id = club_id
        flight.igc_file = igc_file

        flight.model_id = igc_file.guess_model()

        if igc_file.registration:
            flight.registration = igc_file.registration
        else:
            flight.registration = igc_file.guess_registration()

        flight.competition_id = igc_file.competition_id

        fp = flight_path(flight.igc_file, add_elevation=True, max_points=None)

        analyzed = False
        try:
            analyzed = analyse_flight(flight, fp=fp)
        except:
            current_app.logger.exception("analyse_flight() raised an exception")

        if not analyzed:
            files.delete_file(filename)
            results.append(UploadResult.for_parser_error(name, str(prefix)))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            results.append(UploadResult.for_future_flight(name, str(prefix)))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            results.append(UploadResult.for_no_flight(name, str(prefix)))
            continue

        flight.privacy_level = Flight.PrivacyLevel.PRIVATE

        trace = _encode_flight_path(fp, qnh=flight.qnh)
        infringements = get_airspace_infringements(fp, qnh=flight.qnh)

        db.session.add(igc_file)
        db.session.add(flight)

        # flush data to make sure we don't get duplicate files from ZIP files
        db.session.flush()

        # Store data in cache for image creation
        cache_key = hashlib.sha1(
            (to_unicode(flight.id) + u"_" + to_unicode(current_user.id)).encode("utf-8")
        ).hexdigest()

        cache.set(
            "upload_airspace_infringements_" + cache_key, infringements, timeout=15 * 60
        )
        cache.set("upload_airspace_flight_path_" + cache_key, fp, timeout=15 * 60)

        airspace = (
            db.session.query(Airspace)
            .filter(Airspace.id.in_(infringements.keys()))
            .all()
        )

        results.append(
            UploadResult(
                name,
                flight,
                UploadStatus.SUCCESS,
                str(prefix),
                trace,
                airspace,
                cache_key,
            )
        )

        create_flight_notifications(flight)

    db.session.commit()

    results = UploadResultSchema().dump(results, many=True).data

    club_members = []
    if current_user.club_id:
        member_schema = UserSchema(only=("id", "name"))

        club_members = (
            User.query(club_id=current_user.club_id)
            .order_by(func.lower(User.name))
            .filter(User.id != current_user.id)
        )

        club_members = member_schema.dump(club_members.all(), many=True).data

    aircraft_models = (
        AircraftModel.query()
        .order_by(AircraftModel.kind)
        .order_by(AircraftModel.name)
        .all()
    )

    aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data

    return jsonify(
        results=results, club_members=club_members, aircraft_models=aircraft_models
    )
Esempio n. 36
0
def delay_schema():
    return UserSchema(only=('trackingDelay',))