예제 #1
0
파일: club.py 프로젝트: imclab/skylines
def pilots():
    users = User.query(club=g.club).order_by(func.lower(User.name))

    return render_template('clubs/pilots.jinja',
                           active_page='settings',
                           club=g.club,
                           users=users)
예제 #2
0
def index():
    users = User.query() \
        .options(joinedload(User.club)) \
        .order_by(func.lower(User.name))

    return render_template('users/list.jinja',
                           active_page='settings',
                           users=users)
예제 #3
0
def _list(args):
    offset = (args['page'] - 1) * args['per_page']
    limit = args['per_page']

    users = User.query().offset(offset).limit(limit)
    result = user_list_schema.dump(users, many=True)

    return jsonify(result.data)
예제 #4
0
파일: users.py 프로젝트: Adrien81/skylines
def index():
    users = User.query() \
        .options(joinedload(User.club)) \
        .order_by(func.lower(User.name))

    return render_template('users/list.jinja',
                           active_page='settings',
                           users=users)
예제 #5
0
def _list(args):
    offset = (args['page'] - 1) * args['per_page']
    limit = args['per_page']

    users = User.query().offset(offset).limit(limit)
    result = user_list_schema.dump(users, many=True)

    return jsonify(result.data)
    def run(self):
        keyless_users = User.query(tracking_key=None)

        for i, user in enumerate(keyless_users):
            user.generate_tracking_key()

            if i % 25 == 0:
                db.session.flush()

        db.session.commit()
예제 #7
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)
예제 #8
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)
예제 #9
0
def generate_keys():
    """Hidden method that generates missing tracking keys."""

    if not g.current_user or not g.current_user.is_manager():
        abort(403)

    for user in User.query():
        if user.tracking_key is None:
            user.generate_tracking_key()

    db.session.commit()

    return redirect(url_for('.index'))
예제 #10
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)
예제 #11
0
파일: users.py 프로젝트: vdrok/skylines
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)
예제 #12
0
파일: users.py 프로젝트: Adrien81/skylines
def generate_keys():
    """Hidden method that generates missing tracking keys."""

    if not g.current_user or not g.current_user.is_manager():
        abort(403)

    for user in User.query():
        if user.tracking_key is None:
            user.generate_tracking_key()

    db.session.commit()

    return redirect(url_for('.index'))
예제 #13
0
파일: users.py 프로젝트: kerel-fs/skylines
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)
예제 #14
0
    def process(self, *args, **kwargs):
        self.choices = [
            (0, '[' + l_('Unknown or other person') + ']'),
            (g.current_user.id, g.current_user.name),
        ]

        club = g.current_user.club
        if club:
            members = User.query(club_id=club.id) \
                .order_by(User.name) \
                .filter(User.id != g.current_user.id)

            members = [(member.id, member.name) for member in members]

            self.choices.append((club.name, members))

        super(ClubPilotsSelectField, self).process(*args, **kwargs)
예제 #15
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)
예제 #16
0
파일: upload.py 프로젝트: kerel-fs/skylines
    try:
        data = FlightSchema(partial=True).load(json, many=True).data
    except ValidationError, e:
        return jsonify(error='validation-failed', fields=e.messages), 422

    ids = [it.get('id') for it in data]
    if not all(ids):
        return jsonify(error='id-missing'), 422

    user_ids = [it['pilot_id'] for it in data if 'pilot_id' in it]
    user_ids.extend([it['co_pilot_id'] for it in data if 'co_pilot_id' in it])

    model_ids = [it['model_id'] for it in data if 'model_id' in it]

    flights = {flight.id: flight for flight in Flight.query().filter(Flight.id.in_(ids)).all()}
    users = {user.id: user for user in User.query().filter(User.id.in_(user_ids)).all()}
    models = {model.id: model for model in AircraftModel.query().filter(AircraftModel.id.in_(model_ids)).all()}

    for d in data:
        flight = flights.get(d.pop('id'))
        if not flight or not flight.is_writable(g.current_user):
            return jsonify(error='unknown-flight'), 422

        if 'pilot_id' in d and d['pilot_id'] is not None and d['pilot_id'] not in users:
            return jsonify(error='unknown-pilot'), 422

        if 'co_pilot_id' in d and d['co_pilot_id'] is not None and d['co_pilot_id'] not in users:
            return jsonify(error='unknown-copilot'), 422

        if 'model_id' in d and d['model_id'] is not None and d['model_id'] not in models:
            return jsonify(error='unknown-aircraft-model'), 422
예제 #17
0
파일: upload.py 프로젝트: kerel-fs/skylines
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)
예제 #18
0
파일: club.py 프로젝트: Adrien81/skylines
def pilots():
    users = User.query(club=g.club).order_by(func.lower(User.name))

    return render_template(
        'clubs/pilots.jinja', active_page='settings',
        club=g.club, users=users)
예제 #19
0
        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)
예제 #20
0
파일: upload.py 프로젝트: yataOrg/skylines
def verify():
    current_user = User.get(request.user_id)

    json = request.get_json()
    if json is None:
        return jsonify(error="invalid-request"), 400

    try:
        data = FlightSchema(partial=True).load(json, many=True).data
    except ValidationError as e:
        return jsonify(error="validation-failed", fields=e.messages), 422

    ids = [it.get("id") for it in data]
    if not all(ids):
        return jsonify(error="id-missing"), 422

    user_ids = [it["pilot_id"] for it in data if "pilot_id" in it]
    user_ids.extend([it["co_pilot_id"] for it in data if "co_pilot_id" in it])

    model_ids = [it["model_id"] for it in data if "model_id" in it]

    flights = {
        flight.id: flight for flight in Flight.query().filter(Flight.id.in_(ids)).all()
    }
    users = {user.id: user for user in User.query().filter(User.id.in_(user_ids)).all()}
    models = {
        model.id: model
        for model in AircraftModel.query().filter(AircraftModel.id.in_(model_ids)).all()
    }

    for d in data:
        flight = flights.get(d.pop("id"))
        if not flight or not flight.is_writable(current_user):
            return jsonify(error="unknown-flight"), 422

        if "pilot_id" in d and d["pilot_id"] is not None and d["pilot_id"] not in users:
            return jsonify(error="unknown-pilot"), 422

        if (
            "co_pilot_id" in d
            and d["co_pilot_id"] is not None
            and d["co_pilot_id"] not in users
        ):
            return jsonify(error="unknown-copilot"), 422

        if (
            "model_id" in d
            and d["model_id"] is not None
            and d["model_id"] not in models
        ):
            return jsonify(error="unknown-aircraft-model"), 422

        for key in (
            "takeoff_time",
            "scoring_start_time",
            "scoring_end_time",
            "landing_time",
        ):
            if key in d:
                d[key] = d[key].replace(tzinfo=None)

        old_pilot = flight.pilot_id

        for key, value in d.items():
            setattr(flight, key, value)

        if not (
            flight.takeoff_time
            <= flight.scoring_start_time
            <= flight.scoring_end_time
            <= flight.landing_time
        ):
            return jsonify(error="invalid-times"), 422

        if flight.pilot_id != old_pilot and flight.pilot_id:
            flight.club_id = users[flight.pilot_id].club_id

        flight.privacy_level = Flight.PrivacyLevel.PUBLIC
        flight.time_modified = datetime.utcnow()

    db.session.commit()

    for flight_id in flights.keys():
        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 jsonify()
예제 #21
0
파일: upload.py 프로젝트: yataOrg/skylines
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
    )
예제 #22
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
    )
예제 #23
0
def verify():
    current_user = User.get(request.user_id)

    json = request.get_json()
    if json is None:
        return jsonify(error="invalid-request"), 400

    try:
        data = FlightSchema(partial=True).load(json, many=True).data
    except ValidationError as e:
        return jsonify(error="validation-failed", fields=e.messages), 422

    ids = [it.get("id") for it in data]
    if not all(ids):
        return jsonify(error="id-missing"), 422

    user_ids = [it["pilot_id"] for it in data if "pilot_id" in it]
    user_ids.extend([it["co_pilot_id"] for it in data if "co_pilot_id" in it])

    model_ids = [it["model_id"] for it in data if "model_id" in it]

    flights = {
        flight.id: flight for flight in Flight.query().filter(Flight.id.in_(ids)).all()
    }
    users = {user.id: user for user in User.query().filter(User.id.in_(user_ids)).all()}
    models = {
        model.id: model
        for model in AircraftModel.query().filter(AircraftModel.id.in_(model_ids)).all()
    }

    for d in data:
        flight = flights.get(d.pop("id"))
        if not flight or not flight.is_writable(current_user):
            return jsonify(error="unknown-flight"), 422

        if "pilot_id" in d and d["pilot_id"] is not None and d["pilot_id"] not in users:
            return jsonify(error="unknown-pilot"), 422

        if (
            "co_pilot_id" in d
            and d["co_pilot_id"] is not None
            and d["co_pilot_id"] not in users
        ):
            return jsonify(error="unknown-copilot"), 422

        if (
            "model_id" in d
            and d["model_id"] is not None
            and d["model_id"] not in models
        ):
            return jsonify(error="unknown-aircraft-model"), 422

        for key in (
            "takeoff_time",
            "scoring_start_time",
            "scoring_end_time",
            "landing_time",
        ):
            if key in d:
                d[key] = d[key].replace(tzinfo=None)

        old_pilot = flight.pilot_id

        for key, value in d.items():
            setattr(flight, key, value)

        if not (
            flight.takeoff_time
            <= flight.scoring_start_time
            <= flight.scoring_end_time
            <= flight.landing_time
        ):
            return jsonify(error="invalid-times"), 422

        if flight.pilot_id != old_pilot and flight.pilot_id:
            flight.club_id = users[flight.pilot_id].club_id

        flight.privacy_level = Flight.PrivacyLevel.PUBLIC
        flight.time_modified = datetime.utcnow()

    db.session.commit()

    for flight_id in flights.keys():
        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 jsonify()
예제 #24
0
                             .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)


@upload_blueprint.route('/flights/upload/verify', methods=('POST',))
예제 #25
0
파일: pilot.py 프로젝트: imclab/skylines
    def process(self, *args, **kwargs):
        users = User.query(club_id=g.current_user.club_id).order_by(User.name)
        self.choices = [(0, '[unspecified]')]
        self.choices.extend([(user.id, user) for user in users])

        super(ClubPilotsSelectField, self).process(*args, **kwargs)
예제 #26
0
    ids = [it.get('id') for it in data]
    if not all(ids):
        return jsonify(error='id-missing'), 422

    user_ids = [it['pilot_id'] for it in data if 'pilot_id' in it]
    user_ids.extend([it['co_pilot_id'] for it in data if 'co_pilot_id' in it])

    model_ids = [it['model_id'] for it in data if 'model_id' in it]

    flights = {
        flight.id: flight
        for flight in Flight.query().filter(Flight.id.in_(ids)).all()
    }
    users = {
        user.id: user
        for user in User.query().filter(User.id.in_(user_ids)).all()
    }
    models = {
        model.id: model
        for model in AircraftModel.query().filter(
            AircraftModel.id.in_(model_ids)).all()
    }

    for d in data:
        flight = flights.get(d.pop('id'))
        if not flight or not flight.is_writable(g.current_user):
            return jsonify(error='unknown-flight'), 422

        if 'pilot_id' in d and d['pilot_id'] is not None and d[
                'pilot_id'] not in users:
            return jsonify(error='unknown-pilot'), 422