Example #1
0
    def delete(self):
        from skylines.model.igcfile import IGCFile

        for row in db.session.query(IGCFile).filter_by(owner_id=self.id):
            files.delete_file(row.filename)

        db.session.query(IGCFile).filter_by(owner_id=self.id).delete()
        db.session.delete(self)
Example #2
0
    def run(self, flight_id, country_code, airport_name,
            date_from, date_to):

        query = db.session.query(Flight) \
            .outerjoin(Flight.takeoff_airport) \
            .join(IGCFile) \
            .order_by(Flight.id)

        if flight_id is not None:
            print "Filter by flight id: " + str(flight_id)
            query = query.filter(Flight.id == flight_id)

        if country_code is not None:
            print "Filter by takeoff airport country code: " + str(country_code)
            query = query.filter(
                func.lower(Airport.country_code) ==
                func.lower(str(country_code)))

        if airport_name is not None:
            print "Filter by takeoff airport name: " + str(airport_name)
            query = query.filter(
                func.lower(Airport.name) ==
                func.lower(str(airport_name)))

        if date_from is not None:
            try:
                date_from = strptime(date_from, "%Y-%m-%d")
            except:
                print "Cannot parse `from` date."
                sys.exit(1)

            query = query.filter(
                Flight.takeoff_time >=
                datetime.fromtimestamp(mktime(date_from)))

        if date_to is not None:
            try:
                date_to = strptime(date_to, "%Y-%m-%d")
            except:
                print "Cannot parse `to` date."
                sys.exit(1)

            query = query.filter(
                Flight.takeoff_time <=
                datetime.fromtimestamp(mktime(date_to)))

        for flight in query:
            print "Flight: " + str(flight.id) + " " + flight.igc_file.filename
            files.delete_file(flight.igc_file.filename)
            db.session.delete(flight)
            db.session.delete(flight.igc_file)
            db.session.commit()
Example #3
0
def delete(flight_id):
    flight = get_requested_record(Flight, flight_id, joinedload=[Flight.igc_file])

    current_user = User.get(request.user_id)
    if not flight.is_writable(current_user):
        abort(403)

    files.delete_file(flight.igc_file.filename)
    db.session.delete(flight)
    db.session.delete(flight.igc_file)
    db.session.commit()

    return jsonify()
Example #4
0
    def delete(self, **kwargs):
        if not self.flight.is_writable(request.identity):
            raise HTTPForbidden

        if request.method == 'POST':
            files.delete_file(self.flight.igc_file.filename)
            DBSession.delete(self.flight)
            DBSession.delete(self.flight.igc_file)

            redirect('/flights/')
        else:
            return dict(title=_('Delete Flight'),
                        question=_('Are you sure you want to delete this flight?'),
                        action='delete', cancel='.')
Example #5
0
    def run(self, flight_id, country_code, airport_name, date_from, date_to):

        query = db.session.query(Flight) \
            .outerjoin(Flight.takeoff_airport) \
            .join(IGCFile) \
            .order_by(Flight.id)

        if flight_id is not None:
            print "Filter by flight id: " + str(flight_id)
            query = query.filter(Flight.id == flight_id)

        if country_code is not None:
            print "Filter by takeoff airport country code: " + str(
                country_code)
            query = query.filter(
                func.lower(Airport.country_code) == func.lower(
                    str(country_code)))

        if airport_name is not None:
            print "Filter by takeoff airport name: " + str(airport_name)
            query = query.filter(
                func.lower(Airport.name) == func.lower(str(airport_name)))

        if date_from is not None:
            try:
                date_from = strptime(date_from, "%Y-%m-%d")
            except:
                print "Cannot parse `from` date."
                sys.exit(1)

            query = query.filter(Flight.takeoff_time >= datetime.fromtimestamp(
                mktime(date_from)))

        if date_to is not None:
            try:
                date_to = strptime(date_to, "%Y-%m-%d")
            except:
                print "Cannot parse `to` date."
                sys.exit(1)

            query = query.filter(
                Flight.takeoff_time <= datetime.fromtimestamp(mktime(date_to)))

        for flight in query:
            print "Flight: " + str(flight.id) + " " + flight.igc_file.filename
            files.delete_file(flight.igc_file.filename)
            db.session.delete(flight)
            db.session.delete(flight.igc_file)
            db.session.commit()
Example #6
0
def delete():
    if not g.flight.is_writable(g.current_user):
        abort(403)

    if request.method == 'POST':
        files.delete_file(g.flight.igc_file.filename)
        db.session.delete(g.flight)
        db.session.delete(g.flight.igc_file)
        db.session.commit()

        return redirect(url_for('flights.index'))

    return render_template(
        'generic/confirm.jinja',
        title=_('Delete Flight'),
        question=_('Are you sure you want to delete this flight?'),
        action=url_for('.delete'), cancel=url_for('.index'))
Example #7
0
    def run(self, confirm, **kwargs):

        query = db.session.query(Flight) \
            .outerjoin(Flight.takeoff_airport) \
            .join(IGCFile) \
            .order_by(Flight.id)

        query = select(query, **kwargs)

        if not query:
            quit()

        for flight in query:
            print("Flight: " + str(flight.id) + " " + flight.igc_file.filename)

            if confirm:
                files.delete_file(flight.igc_file.filename)
                db.session.delete(flight)
                db.session.delete(flight.igc_file)
                db.session.commit()
Example #8
0
    def do(self, file, pilot):
        user = request.identity['user']

        pilot_id = None
        club_id = user.club_id
        if pilot:
            pilot = DBSession.query(User).get(int(pilot))
            if pilot:
                pilot_id = pilot.id
                club_id = pilot.club_id

        flights = []
        success = False

        for name, f in IterateUploadFiles(file):
            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)
                    flights.append((name, other, _('Duplicate file')))
                    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)
                flights.append((name, None, _('Date missing in IGC file')))
                continue

            flight = Flight()
            flight.pilot_id = pilot_id
            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

            if not analyse_flight(flight):
                files.delete_file(filename)
                flights.append((name, None, _('Failed to parse file')))
                continue

            if not flight.takeoff_time or not flight.landing_time:
                files.delete_file(filename)
                flights.append((name, None, _('No flight found in file')))
                continue

            if not flight.update_flight_path():
                files.delete_file(filename)
                flights.append((name, None, _('No flight found in file')))
                continue

            flights.append((name, flight, None))
            DBSession.add(igc_file)
            DBSession.add(flight)

            create_flight_notifications(flight)

            success = True

        DBSession.flush()

        return dict(flights=flights, success=success,
                    ModelSelectField=aircraft_model.SelectField)
Example #9
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

    flights = []
    success = False

    prefix = 0
    for name, f in IterateUploadFiles(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)
                flights.append((name, other, UploadStatus.DUPLICATE, str(prefix), None))
                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)
            flights.append((name, None, UploadStatus.MISSING_DATE, str(prefix), None))
            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

        if not analyse_flight(flight):
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.PARSER_ERROR, str(prefix), None))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None))
            continue

        flights.append((name, flight, UploadStatus.SUCCESS, str(prefix),
                        ChangeAircraftForm(formdata=None, prefix=str(prefix), obj=flight)))
        db.session.add(igc_file)
        db.session.add(flight)

        create_flight_notifications(flight)

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

        success = True

    db.session.commit()

    try:
        for flight in flights:
            if flight[2] is UploadStatus.SUCCESS:
                tasks.analyse_flight.delay(flight[1].id)
                tasks.find_meetings.delay(flight[1].id)
    except ConnectionError:
        current_app.logger.info('Cannot connect to Redis server')

    return render_template(
        'upload/result.jinja', num_flights=prefix, flights=flights, success=success)
Example #10
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

    flights = []
    success = False

    prefix = 0
    for name, f in IterateUploadFiles(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)
                flights.append((name, other, UploadStatus.DUPLICATE, str(prefix), None, None, None, None))
                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)
            flights.append((name, None, UploadStatus.MISSING_DATE, str(prefix), None, None, None, None))
            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)

        if not analyse_flight(flight, fp=fp):
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.PARSER_ERROR, str(prefix), None, None, None, None))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None, None, None, None))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.FLIGHT_IN_FUTURE, str(prefix), None, None, None, None))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None, None, None, None))
            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()

        # create form after flushing the session, otherwise we wouldn't have a flight.id
        form = UploadUpdateForm(formdata=None, prefix=str(prefix), obj=flight)
        # remove airspace field from form if no airspace infringements found
        if not infringements:
            del form.airspace_usage

        # replace None in form.pilot_id and form.co_pilot_id with 0
        if not form.pilot_id.data: form.pilot_id.data = 0
        if not form.co_pilot_id.data: form.co_pilot_id.data = 0

        form.pilot_id.validate(form)

        flights.append((name, flight, UploadStatus.SUCCESS, str(prefix), trace,
                        airspace, cache_key, form))

        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.'))

    return render_template(
        'upload/result.jinja', num_flights=prefix, flights=flights, success=success)
Example #11
0
    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()
Example #12
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
    )
Example #13
0
    print "Filter by takeoff airport country code: " + str(args.country_code)
    query = query.filter(func.lower(Airport.country_code) == func.lower(str(args.country_code)))

if args.airport_name is not None:
    print "Filter by takeoff airport name: " + str(args.airport_name)
    query = query.filter(func.lower(Airport.name) == func.lower(str(args.airport_name)))

if args.date_from is not None:
    try:
        date_from = strptime(args.date_from, "%Y-%m-%d")
    except:
        parser.error("Cannot parse `from` date.")

    query = query.filter(Flight.takeoff_time >= datetime.fromtimestamp(mktime(date_from)))

if args.date_to is not None:
    try:
        date_to = strptime(args.date_to, "%Y-%m-%d")
    except:
        parser.error("Cannot parse `to` date.")

    query = query.filter(Flight.takeoff_time <= datetime.fromtimestamp(mktime(date_to)))


for flight in query:
    print "Flight: " + str(flight.id) + " " + flight.igc_file.filename
    files.delete_file(flight.igc_file.filename)
    db.session.delete(flight)
    db.session.delete(flight.igc_file)
    db.session.commit()
Example #14
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)
Example #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

    flights = []
    success = False

    for name, f in IterateUploadFiles(form.file.raw_data):
        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)
                flights.append((name, other, _('Duplicate file')))
                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)
            flights.append((name, None, _('Date missing in IGC file')))
            continue

        flight = Flight()
        flight.pilot_id = pilot_id
        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

        if not analyse_flight(flight):
            files.delete_file(filename)
            flights.append((name, None, _('Failed to parse file')))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            flights.append((name, None, _('No flight found in file')))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            flights.append((name, None, _('No flight found in file')))
            continue

        flights.append((name, flight, None))
        db.session.add(igc_file)
        db.session.add(flight)

        create_flight_notifications(flight)

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

        success = True

    db.session.commit()

    try:
        for flight in flights:
            if flight[2] is None:
                tasks.analyse_flight.delay(flight[1].id)
    except ConnectionError:
        app.logger.info('Cannot connect to Redis server')

    def ModelSelectField(*args, **kwargs):
        return AircraftModelSelectField().bind(None, 'model', *args, **kwargs)()

    return render_template(
        'upload/result.jinja', flights=flights, success=success,
        ModelSelectField=ModelSelectField)
Example #16
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

    flights = []
    success = False

    prefix = 0
    for name, f in IterateUploadFiles(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)
                flights.append((name, other, UploadStatus.DUPLICATE, str(prefix), None, None, None, None))
                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)
            flights.append((name, None, UploadStatus.MISSING_DATE, str(prefix), None, None, None, None))
            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:
            analyse_flight(flight, fp=fp)
            analyzed = True
        except:
            current_app.logger.exception('analyse_flight() raised an exception')

        if not analyzed:
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.PARSER_ERROR, str(prefix), None, None, None, None))
            continue

        if not flight.takeoff_time or not flight.landing_time:
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None, None, None, None))
            continue

        if flight.landing_time > datetime.now():
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.FLIGHT_IN_FUTURE, str(prefix), None, None, None, None))
            continue

        if not flight.update_flight_path():
            files.delete_file(filename)
            flights.append((name, None, UploadStatus.NO_FLIGHT, str(prefix), None, None, None, None))
            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()

        # create form after flushing the session, otherwise we wouldn't have a flight.id
        form = UploadUpdateForm(formdata=None, prefix=str(prefix), obj=flight)
        # remove airspace field from form if no airspace infringements found
        if not infringements:
            del form.airspace_usage

        # replace None in form.pilot_id and form.co_pilot_id with 0
        if not form.pilot_id.data: form.pilot_id.data = 0
        if not form.co_pilot_id.data: form.co_pilot_id.data = 0

        form.pilot_id.validate(form)

        flights.append((name, flight, UploadStatus.SUCCESS, str(prefix), trace,
                        airspace, cache_key, form))

        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.'))

    return render_template(
        'upload/result.jinja', num_flights=prefix, flights=flights, success=success)