示例#1
0
def all_features(pid):
    project = Project.get(Project.id == pid)
    query = Feature.select().where(Feature.project == project)
    features = []
    for f in query:
        features.append([f.ref, [f.lat/1e7, f.lon/1e7], f.action])
    return app.response_class('features = {}'.format(json.dumps(
        features, ensure_ascii=False).encode('utf-8')), mimetype='application/javascript')
示例#2
0
def export_audit(pid):
    project = Project.get(Project.id == pid)
    if not is_admin(get_user(), project):
        return redirect(url_for('front'))
    update_audit(project)
    project.save()
    return app.response_class(
        project.audit or '{}', mimetype='application/json',
        headers={'Content-Disposition': 'attachment;filename=audit_{}.json'.format(project.name)})
示例#3
0
def external_audit(pid):
    project = Project.get(Project.id == pid)
    if not is_admin(get_user(), project):
        return redirect(url_for('front'))
    query = Feature.select().where(Feature.project == project,
                                   Feature.audit.is_null(False))
    result = {}
    for feat in query:
        audit = json.loads(feat.audit or {})
        props = json.loads(feat.feature)['properties']
        eaudit = {}
        if 'move' in audit:
            if audit['move'] == 'osm':
                if 'were_coords' in props['were_coords']:
                    eaudit['move'] = props['were_coords']
            elif isinstance(audit['move'], list) and len(audit['move']) == 2:
                eaudit['move'] = audit['move']
        if 'keep' in audit:
            keep = {}
            for k in audit['keep']:
                orig = None
                if 'tags_deleted.' + k in props:
                    orig = props['tags_deleted.' + k]
                elif 'tags_changed.' + k in props:
                    orig = props['tags_changed.' + k]
                    orig = orig[:orig.find(' -> ')]
                if orig:
                    keep[k] = orig
            if keep:
                eaudit['keep'] = keep
        if audit.get('skip'):
            if audit.get('comment', '').lower() != 'duplicate':
                eaudit['skip'] = audit.get('comment', '<no reason>')
        if eaudit:
            result[feat.ref] = eaudit
    return app.response_class(
        json.dumps(result, ensure_ascii=False, indent=1, sort_keys=True),
        mimetype='application/json',
        headers={
            'Content-Disposition':
            'attachment;filename=ext_audit_{}.json'.format(project.name)
        })
示例#4
0
def all_features(pid):
    project = Project.get(Project.id == pid)
    region = request.args.get('region')
    if region:
        query = Feature.select(Feature.ref, Feature.lat, Feature.lon,
                               Feature.action).where(
                                   Feature.project == project,
                                   Feature.region == region).tuples()
        features = []
        for ref, lat, lon, action in query:
            features.append([ref, [lat / 1e7, lon / 1e7], action])
        features_js = json.dumps(features, ensure_ascii=False)
    else:
        if not project.features_js:
            update_features_cache(project)
            try:
                project.save()
            except OperationalError:
                # Sometimes wait is too long and MySQL disappears
                pass
        features_js = project.features_js
    return app.response_class('features = {}'.format(features_js),
                              mimetype='application/javascript')
示例#5
0
def render():
    options = {}
    variables = {}

    # bounding box
    if 'bbox' in request.form:
        bbox = request.form['bbox']
        if re.match('^[0-9.-]+(?:,[0-9.-]+){3}$', bbox):
            options['bbox'] = ' '.join(bbox.split(','))

    # image dimensions
    mode = request.form.get('dim', 'both')
    if mode == 'zoom' and 'zoom' in request.form:
        zoom = request.form['zoom']
        if re.match('^\d\d?$', zoom):
            options['zoom'] = zoom
    elif 'width' in request.form or 'height' in request.form:
        dim = '{} {}'.format(
            request.form.get('width', '0') if mode != 'height' else 0,
            request.form.get('height', '0') if mode != 'width' else 0)
        if not re.match('^\d{1,5} \d{1,5}$', dim):
            return 'Dimensions are  incorrect: ' + dim
        if request.form.get('units', '') == 'px':
            whkey = 'size-px'
        else:
            whkey = 'size'
            options['ppi'] = '300'
        options[whkey] = dim
        if 'margin' in request.form:
            margin = request.form['margin']
            if re.match('^\d\d?$', margin):
                options['margin'] = margin
        if mode == 'width' or mode == 'height':
            options['norotate'] = None

        # test for size limit
        size = dim.split(' ')
        mult = max(int(size[0]), int(size[1]))
        mult = mult * mult
        if 'ppi' in options:
            mult = mult * 16
        if mult > 2000 * 2000:
            return 'Dimensions are too big'

    # GPX trace (specific to veloroad style)
    traceFile = None
    if config.ROUTE and 'trace' in request.files and request.files[
            'trace'].filename:
        traceFile = tempfile.NamedTemporaryFile('wb+', delete=False)
        request.files['trace'].save(traceFile)
        traceFile.close()

        variables['route'] = traceFile.name
        if 'fit' in request.form:
            del options['bbox']
            if 'norotate' in options:
                del options['norotate']
            options['fit'] = config.ROUTE
        if 'drawtrace' in request.form:
            options['add-layers'] = config.ROUTE

    # scale bar (specific to veloroad style)
    if config.SCALE and 'scale' in request.form:
        scalepos = request.form.get('scalepos', '')
        if re.match('^[0-9.-]+, *[0-9.-]+$', scalepos):
            options['add-layers'] = ','.join([
                config.ROUTE, config.SCALE
            ]) if 'add-layers' in options else config.SCALE
            variables['scale'] = scalepos
            scalens = re.match('^([1-9])-([1-5][05]?)$',
                               request.form.get('scalens', '5-1'))
            variables['scalen'] = scalens.group(1) if scalens else 5
            variables['scales'] = scalens.group(2) if scalens else 1

    # map style, file format and mime type
    style = request.form.get('style', '')
    styles = {s[0]: [s[2], s[3]] for s in config.STYLES}
    if style not in styles:
        style = config.STYLES[0][0]

    fmt = request.form.get('format', '')
    formats = {f[0]: f[2] for f in config.FORMATS}
    if fmt not in formats:
        fmt = config.FORMATS[0][0]
    options['format'] = fmt
    mime = formats[fmt]

    # build command line for nik4
    outfile, outputName = tempfile.mkstemp()
    command = ['/usr/bin/env', config.PYTHON, config.NIK4]
    for k, v in options.items():
        command.append('--{}'.format(k))
        if v is not None:
            command.extend(v.split(' '))
    command.append(styles[style][0])
    command.append(outputName)
    if styles[style][1]:
        command.append('--vars')
        for k, v in variables.items():
            command.append('{}={}'.format(k, v))

    # check for running nik4
    ps = subprocess.Popen('ps -e|grep nik4.py',
                          shell=True,
                          stdout=subprocess.PIPE)
    psout, _ = ps.communicate()
    if b'nik4' in psout:
        if traceFile:
            os.remove(traceFile.name)
        return 'Nik4 is running, please try later.'

    # start nik4 process
    process = subprocess.Popen(command, stderr=subprocess.PIPE)
    _, err = process.communicate()
    code = process.returncode
    # Remove the temporary trace file
    if traceFile:
        os.remove(traceFile.name)
    if code == 0 and os.stat(outputName).st_size > 0:
        if fmt == 'svg':
            # run mapnik-group-text
            from mapnik_group_text import mapnik_group_text as mgt
            mgt_opt = {'dmax': 60, 'group': True}
            mgt.process_stream(open(outputName, 'rb'), outputName, mgt_opt)
            # run svn-resize if dimensions are known
            if 'size' in options or 'size-px' in options:
                from svg_resize import svg_resize as svgr
                svgr_opt = {}
                if 'size' in options:
                    d = options['size'].split(' ')
                    suffix = 'mm'
                else:
                    d = options['size-px'].split(' ')
                    suffix = 'px'
                if 'norotate' in options or not d[0] or not d[1]:
                    if d[0]:
                        svgr_opt['width'] = d[0] + suffix
                    if d[1]:
                        svgr_opt['height'] = d[1] + suffix
                else:
                    svgr_opt['longest'] = max(d[0], d[1]) + suffix
                    svgr_opt['shortest'] = min(d[0], d[1]) + suffix
                if 'margin' in options:
                    svgr_opt['margin'] = options['margin']
                svgr_opt['frame'] = True
                svgr_opt['input'] = outputName
                svgr.process_stream(svgr_opt)
        afn = '{}-{}.{}'.format(
            style,
            datetime.datetime.now().strftime('%y%m%d-%H%M'), fmt)
        fp = tempfile.TemporaryFile()
        with open(outputName, 'rb') as f:
            shutil.copyfileobj(f, fp)
        os.remove(outputName)
        fp.seek(0)
        return send_file(fp,
                         mimetype=mime,
                         add_etags=False,
                         as_attachment=True,
                         attachment_filename=afn)

    else:
        os.remove(outputName)
        if code > 0:
            msg = 'Error {} happened.'.format(code)
        else:
            msg = 'Resulting file is empty.'
        msg += '\nCommand line:\n{}\n\nOutput:\n'.format(' '.join(command))
        msg += err.decode('utf-8')
        return app.response_class(msg, mimetype='text/plain')
示例#6
0
def robots():
    return app.response_class('User-agent: *\nDisallow: /',
                              mimetype='text/plain')
示例#7
0
文件: mmwatch.py 项目: Zverik/mmwatch
def no_robots():
    return app.response_class('User-agent: *\nDisallow: /', mimetype='text/plain')