Beispiel #1
0
    def run(self, path):
        for line in file(path):
            m = r.match(line)
            if m:
                names, index = m.group(1), int(m.group(2))
                for name in names.split(';'):
                    name = name.strip().decode('utf-8')
                    model = AircraftModel.by_name(name)
                    if model is None:
                        model = AircraftModel(name=name)
                        model.kind = 1
                        db.session.add(model)
                    model.dmst_index = index

        db.session.commit()
Beispiel #2
0
    def run(self, path):
        for line in file(path):
            m = r.match(line)
            if m:
                names, index = m.group(1), int(m.group(2))
                for name in names.split(';'):
                    name = name.strip().decode('utf-8')
                    model = AircraftModel.by_name(name)
                    if model is None:
                        model = AircraftModel(name=name)
                        model.kind = 1
                        db.session.add(model)
                    model.dmst_index = index

        db.session.commit()
Beispiel #3
0
def nimeta(**kwargs):
    return AircraftModel(
        name='Nimeta',
        kind=1,
        igc_index=142,
        dmst_index=112,
    ).apply_kwargs(kwargs)
    def process(self, *args, **kwargs):
        models = AircraftModel.query() \
            .order_by(AircraftModel.kind) \
            .order_by(AircraftModel.name) \
            .all()

        gliders = [(model.id, model) for model in models if model.kind == 1]
        motor_gliders = [(model.id, model) for model in models
                         if model.kind == 2]
        hanggliders = [(model.id, model) for model in models
                       if model.kind == 3]
        paragliders = [(model.id, model) for model in models
                       if model.kind == 4]
        ul_gliders = [(model.id, model) for model in models if model.kind == 5]

        self.choices = []

        if len(gliders) > 0: self.choices.append((_('Gliders'), gliders))
        if len(motor_gliders) > 0:
            self.choices.append((_('Motor Gliders'), motor_gliders))
        if len(hanggliders) > 0:
            self.choices.append((_('Hanggliders'), hanggliders))
        if len(paragliders) > 0:
            self.choices.append((_('Paragliders'), paragliders))
        if len(ul_gliders) > 0:
            self.choices.append((_('UL Gliders'), ul_gliders))

        self.choices.append((_('Other'), [(0, '[unspecified]')]))

        super(AircraftModelSelectField, self).process(*args, **kwargs)
Beispiel #5
0
def hornet(**kwargs):
    return AircraftModel(
        name='Hornet',
        kind=1,
        igc_index=100,
        dmst_index=100,
    ).apply_kwargs(kwargs)
Beispiel #6
0
def index():
    models = AircraftModel.query() \
        .order_by(AircraftModel.kind) \
        .order_by(AircraftModel.name) \
        .all()

    return jsonify(models=AircraftModelSchema().dump(models, many=True).data)
Beispiel #7
0
    def guess_model(self):
        from skylines.model import Flight, AircraftModel

        # first try to find the reg number in the database
        if self.registration is not None:
            glider_reg = self.registration

            result = Flight.query() \
                .filter(db.func.upper(Flight.registration) == db.func.upper(glider_reg)) \
                .order_by(Flight.id.desc()) \
                .first()

            if result and result.model_id:
                return result.model_id

        # try to find another flight with the same logger and use it's aircraft type
        if (self.logger_id is not None
                and self.logger_manufacturer_id is not None):
            logger_id = self.logger_id
            logger_manufacturer_id = self.logger_manufacturer_id

            result = Flight.query().join(IGCFile) \
                .filter(db.func.upper(IGCFile.logger_manufacturer_id) == db.func.upper(logger_manufacturer_id)) \
                .filter(db.func.upper(IGCFile.logger_id) == db.func.upper(logger_id)) \
                .filter(Flight.model_id == None) \
                .order_by(Flight.id.desc())

            if self.logger_manufacturer_id.startswith('X'):
                result = result.filter(Flight.pilot == self.owner)

            result = result.first()

            if result and result.model_id:
                return result.model_id

        if self.model is not None:
            glider_type = self.model.lower()

            # otherwise, try to guess the glider model by the glider type igc header
            text_fragments = ['%{}%'.format(v) for v in re.sub(r'[^a-z]', ' ', glider_type).split()]
            digit_fragments = ['%{}%'.format(v) for v in re.sub(r'[^0-9]', ' ', glider_type).split()]

            if not text_fragments and not digit_fragments:
                return None

            glider_type_clean = re.sub(r'[^a-z0-9]', '', glider_type)

            result = AircraftModel.query() \
                .filter(and_(
                    db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^a-z]', ' ').like(db.func.any(text_fragments)),
                    db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^0-9]', ' ').like(db.func.all(digit_fragments)))) \
                .order_by(db.func.levenshtein(db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^a-z0-9]', ''), glider_type_clean))

            if result.first():
                return result.first().id

        # nothing found
        return None
Beispiel #8
0
    def guess_model(self):
        from skylines.model import Flight, AircraftModel

        # first try to find the reg number in the database
        if self.registration is not None:
            glider_reg = self.registration

            result = Flight.query() \
                .filter(db.func.upper(Flight.registration) == db.func.upper(glider_reg)) \
                .order_by(Flight.id.desc()) \
                .first()

            if result and result.model_id:
                return result.model_id

        # try to find another flight with the same logger and use it's aircraft type
        if (self.logger_id is not None and
                self.logger_manufacturer_id is not None):
            logger_id = self.logger_id
            logger_manufacturer_id = self.logger_manufacturer_id

            result = Flight.query().join(IGCFile) \
                .filter(db.func.upper(IGCFile.logger_manufacturer_id) == db.func.upper(logger_manufacturer_id)) \
                .filter(db.func.upper(IGCFile.logger_id) == db.func.upper(logger_id)) \
                .filter(Flight.model_id == None) \
                .order_by(Flight.id.desc())

            if self.logger_manufacturer_id.startswith('X'):
                result = result.filter(Flight.pilot == self.owner)

            result = result.first()

            if result and result.model_id:
                return result.model_id

        if self.model is not None:
            glider_type = self.model.lower()

            # otherwise, try to guess the glider model by the glider type igc header
            text_fragments = ['%{}%'.format(v) for v in re.sub(r'[^a-z]', ' ', glider_type).split()]
            digit_fragments = ['%{}%'.format(v) for v in re.sub(r'[^0-9]', ' ', glider_type).split()]

            if not text_fragments and not digit_fragments:
                return None

            glider_type_clean = re.sub(r'[^a-z0-9]', '', glider_type)

            result = AircraftModel.query() \
                .filter(and_(
                    db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^a-z]', ' ').like(db.func.any(text_fragments)),
                    db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^0-9]', ' ').like(db.func.all(digit_fragments)))) \
                .order_by(db.func.levenshtein(db.func.regexp_replace(db.func.lower(AircraftModel.name), '[^a-z0-9]', ''), glider_type_clean))

            if result.first():
                return result.first().id

        # nothing found
        return None
Beispiel #9
0
def add_model(name, kind=0, index=0):
    """ Add a new aircraft model to the database """

    model = AircraftModel(name=name, kind=kind)
    if index > 0:
        model.igc_index = model.dmst_index = index

    db.session.add(model)
    db.session.commit()
Beispiel #10
0
    def get_model(self):
        from skylines.model import AircraftModel

        if self.model is not None:
            result = (AircraftModel.query().filter(
                AircraftModel.name == self.model))
            if result.first():
                return result.first().id
        # nothing found
        return None
Beispiel #11
0
    def process(self, *args, **kwargs):
        models = AircraftModel.query() \
            .order_by(AircraftModel.kind) \
            .order_by(AircraftModel.name) \
            .all()

        gliders = [(model.id, model) for model in models if model.kind == 1]
        motor_gliders = [(model.id, model) for model in models if model.kind == 2]
        hanggliders = [(model.id, model) for model in models if model.kind == 3]
        paragliders = [(model.id, model) for model in models if model.kind == 4]
        ul_gliders = [(model.id, model) for model in models if model.kind == 5]

        self.choices = []

        if len(gliders) > 0: self.choices.append((_('Gliders'), gliders))
        if len(motor_gliders) > 0: self.choices.append((_('Motor Gliders'), motor_gliders))
        if len(hanggliders) > 0: self.choices.append((_('Hanggliders'), hanggliders))
        if len(paragliders) > 0: self.choices.append((_('Paragliders'), paragliders))
        if len(ul_gliders) > 0: self.choices.append((_('UL Gliders'), ul_gliders))

        self.choices.append((_('Other'), [(0, '[unspecified]')]))

        super(AircraftModelSelectField, self).process(*args, **kwargs)
Beispiel #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
    )
Beispiel #13
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()
Beispiel #14
0
def list():
    """ Shows the list of aircrafts"""
    aircraftModels = AircraftModel.query().all()
    return aircraftModels
Beispiel #15
0
def ask13(**kwargs):
    return AircraftModel(name=u"ASK 13", igc_index=42,
                         dmst_index=17).apply_kwargs(kwargs)
Beispiel #16
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()
Beispiel #17
0
                    metavar='config.ini',
                    help='path to the configuration INI file')
parser.add_argument('path', help='DMSt index list file')

args = parser.parse_args()

if not to_envvar(args.config):
    parser.error('Config file "{}" not found.'.format(args.config))

import re
from skylines import db
from skylines.config import environment
from skylines.model import AircraftModel

r = re.compile(r'^(.*?)\s*\.+[\.\s]*(\d+)\s*$')

for line in file(args.path):
    m = r.match(line)
    if m:
        names, index = m.group(1), int(m.group(2))
        for name in names.split(';'):
            name = name.strip().decode('utf-8')
            model = AircraftModel.by_name(name)
            if model is None:
                model = AircraftModel(name=name)
                model.kind = 1
                db.session.add(model)
            model.dmst_index = index

db.session.commit()
Beispiel #18
0
    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',))
@oauth.required()
def verify():
    current_user = User.get(request.user_id)

    json = request.get_json()
    if json is None:
        return jsonify(error='invalid-request'), 400
Beispiel #19
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)
Beispiel #20
0
def epsilon(**kwargs):
    return AircraftModel(
        name='EPSILON',
        kind=3,
    ).apply_kwargs(kwargs)
Beispiel #21
0
def falcon9(**kwargs):
    return AircraftModel(name=u"Falcon 9", kind=5).apply_kwargs(kwargs)
Beispiel #22
0
def delta(**kwargs):
    return AircraftModel(name=u"Δ", kind=4).apply_kwargs(kwargs)
Beispiel #23
0
def epsilon(**kwargs):
    return AircraftModel(name=u"EPSILON", kind=3).apply_kwargs(kwargs)
Beispiel #24
0
def dimona(**kwargs):
    return AircraftModel(name=u"Dimona", kind=2).apply_kwargs(kwargs)
Beispiel #25
0
    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
Beispiel #26
0
        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
Beispiel #27
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
    )
Beispiel #28
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)
Beispiel #29
0
def update(flight_id):
    flight = get_requested_record(Flight, flight_id)

    current_user = User.get(request.user_id)
    if not flight.is_writable(current_user):
        return jsonify(), 403

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

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

    if 'pilot_id' in data:
        pilot_id = data['pilot_id']

        if pilot_id is not None:

            if not User.exists(id=pilot_id):
                return jsonify(error='unknown-pilot'), 422

            pilot_club_id = User.get(pilot_id).club_id

            if pilot_club_id != current_user.club_id or (
                    pilot_club_id is None and pilot_id != current_user.id):
                return jsonify(error='pilot-disallowed'), 422

            if flight.pilot_id != pilot_id:
                flight.pilot_id = pilot_id
                # pilot_name is irrelevant, if pilot_id is given
                flight.pilot_name = None
                # update club if pilot changed
                flight.club_id = pilot_club_id

        else:
            flight.pilot_id = None

    if 'pilot_name' in data:
        flight.pilot_name = data['pilot_name']

    if 'co_pilot_id' in data:
        co_pilot_id = data['co_pilot_id']

        if co_pilot_id is not None:

            if not User.exists(id=co_pilot_id):
                return jsonify(error='unknown-copilot'), 422

            co_pilot_club_id = User.get(co_pilot_id).club_id

            if co_pilot_club_id != current_user.club_id \
                    or (co_pilot_club_id is None and co_pilot_id != current_user.id):
                return jsonify(error='co-pilot-disallowed'), 422

            flight.co_pilot_id = co_pilot_id
            # co_pilot_name is irrelevant, if co_pilot_id is given
            flight.co_pilot_name = None

        else:
            flight.co_pilot_id = None

    if 'co_pilot_name' in data:
        flight.co_pilot_name = data['co_pilot_name']

    if flight.co_pilot_id is not None and flight.co_pilot_id == flight.pilot_id:
        return jsonify(error='copilot-equals-pilot'), 422

    if 'model_id' in data:
        model_id = data['model_id']

        if model_id is not None and not AircraftModel.exists(id=model_id):
            return jsonify(error='unknown-aircraft-model'), 422

        flight.model_id = model_id

    if 'registration' in data:
        flight.registration = data['registration']

    if 'competition_id' in data:
        flight.competition_id = data['competition_id']

    if 'privacy_level' in data:
        flight.privacy_level = data['privacy_level']

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

    flight.time_modified = datetime.utcnow()
    db.session.commit()

    return jsonify()
Beispiel #30
0
    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', ))
@oauth.required()
def verify():
    current_user = User.get(request.user_id)
Beispiel #31
0
def remove_model(index):
    """ Remove the aircraft model from database """
    AircraftModel.query(id=index).delete()
    db.session.commit()
Beispiel #32
0
        if co_pilot_id is not None and not User.exists(id=co_pilot_id):
            return jsonify(error='unknown-copilot'), 422

        g.flight.co_pilot_id = co_pilot_id

    if 'co_pilot_name' in data:
        g.flight.co_pilot_name = data['co_pilot_name']

    if g.flight.co_pilot_id is not None and g.flight.co_pilot_id == g.flight.pilot_id:
        return jsonify(error='copilot-equals-pilot'), 422

    if 'model_id' in data:
        model_id = data['model_id']

        if model_id is not None and not AircraftModel.exists(id=model_id):
            return jsonify(error='unknown-aircraft-model'), 422

        g.flight.model_id = model_id

    if 'registration' in data:
        g.flight.registration = data['registration']

    if 'competition_id' in data:
        g.flight.competition_id = data['competition_id']

    g.flight.time_modified = datetime.utcnow()
    db.session.commit()

    return jsonify()
Beispiel #33
0
def falcon9(**kwargs):
    return AircraftModel(
        name='Falcon 9',
        kind=5,
    ).apply_kwargs(kwargs)
Beispiel #34
0
def update(flight_id):
    flight = get_requested_record(Flight, flight_id)

    current_user = User.get(request.user_id)
    if not flight.is_writable(current_user):
        return jsonify(), 403

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

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

    if "pilot_id" in data:
        pilot_id = data["pilot_id"]

        if pilot_id is not None:

            if not User.exists(id=pilot_id):
                return jsonify(error="unknown-pilot"), 422

            pilot_club_id = User.get(pilot_id).club_id

            if pilot_club_id != current_user.club_id or (
                pilot_club_id is None and pilot_id != current_user.id
            ):
                return jsonify(error="pilot-disallowed"), 422

            if flight.pilot_id != pilot_id:
                flight.pilot_id = pilot_id
                # pilot_name is irrelevant, if pilot_id is given
                flight.pilot_name = None
                # update club if pilot changed
                flight.club_id = pilot_club_id

        else:
            flight.pilot_id = None

    if "pilot_name" in data:
        flight.pilot_name = data["pilot_name"]

    if "co_pilot_id" in data:
        co_pilot_id = data["co_pilot_id"]

        if co_pilot_id is not None:

            if not User.exists(id=co_pilot_id):
                return jsonify(error="unknown-copilot"), 422

            co_pilot_club_id = User.get(co_pilot_id).club_id

            if co_pilot_club_id != current_user.club_id or (
                co_pilot_club_id is None and co_pilot_id != current_user.id
            ):
                return jsonify(error="co-pilot-disallowed"), 422

            flight.co_pilot_id = co_pilot_id
            # co_pilot_name is irrelevant, if co_pilot_id is given
            flight.co_pilot_name = None

        else:
            flight.co_pilot_id = None

    if "co_pilot_name" in data:
        flight.co_pilot_name = data["co_pilot_name"]

    if flight.co_pilot_id is not None and flight.co_pilot_id == flight.pilot_id:
        return jsonify(error="copilot-equals-pilot"), 422

    if "model_id" in data:
        model_id = data["model_id"]

        if model_id is not None and not AircraftModel.exists(id=model_id):
            return jsonify(error="unknown-aircraft-model"), 422

        flight.model_id = model_id

    if "registration" in data:
        flight.registration = data["registration"]

    if "competition_id" in data:
        flight.competition_id = data["competition_id"]

    if "privacy_level" in data:
        flight.privacy_level = data["privacy_level"]

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

    flight.time_modified = datetime.utcnow()
    db.session.commit()

    return jsonify()
Beispiel #35
0
def dimona(**kwargs):
    return AircraftModel(
        name='Dimona',
        kind=2,
    ).apply_kwargs(kwargs)
Beispiel #36
0
            # co_pilot_name is irrelevant, if co_pilot_id is given
            flight.co_pilot_name = None

        else:
            flight.co_pilot_id = None

    if 'co_pilot_name' in data:
        flight.co_pilot_name = data['co_pilot_name']

    if flight.co_pilot_id is not None and flight.co_pilot_id == flight.pilot_id:
        return jsonify(error='copilot-equals-pilot'), 422

    if 'model_id' in data:
        model_id = data['model_id']

        if model_id is not None and not AircraftModel.exists(id=model_id):
            return jsonify(error='unknown-aircraft-model'), 422

        flight.model_id = model_id

    if 'registration' in data:
        flight.registration = data['registration']

    if 'competition_id' in data:
        flight.competition_id = data['competition_id']

    if 'privacy_level' in data:
        flight.privacy_level = data['privacy_level']

        try:
            tasks.analyse_flight.delay(flight.id)
Beispiel #37
0
parser.add_argument('--config', metavar='config.ini',
                    help='path to the configuration INI file')
parser.add_argument('path', help='DMSt index list file')

args = parser.parse_args()

if not to_envvar(args.config):
    parser.error('Config file "{}" not found.'.format(args.config))


import re
from skylines import db
from skylines.model import AircraftModel

r = re.compile(r'^(.*?)\s*\.+[\.\s]*(\d+)\s*$')

for line in file(args.path):
    m = r.match(line)
    if m:
        names, index = m.group(1), int(m.group(2))
        for name in names.split(';'):
            name = name.strip().decode('utf-8')
            model = AircraftModel.by_name(name)
            if model is None:
                model = AircraftModel(name=name)
                model.kind = 1
                db.session.add(model)
            model.dmst_index = index

db.session.commit()
Beispiel #38
0
def delta(**kwargs):
    return AircraftModel(
        name=u'Δ',
        kind=4,
    ).apply_kwargs(kwargs)