<commit_before>import socket
import time

from flask import Blueprint, current_app, request
from flask_security import current_user, login_required, roles_accepted
import redis

from APITaxi_models2 import db, Taxi, Vehicle, VehicleDescription

from .. import schemas
from ..validators import (
    make_error_json_response,
    validate_schema
)


blueprint = Blueprint('geotaxi', __name__)


def _run_redis_action(pipe, action, *params):
    action = getattr(pipe, action.lower())

    # Run action
    try:
        action(*params)
    except socket.error:
        current_app.logger.error(
            'Error while running redis action %s %s',
            action.__name__.upper(),
            ' '.join([str(param) for param in params])
        )
    except redis.RedisError as e:
        current_app.logger.error(
            'Error while running redis action %s %s %s',
            action.__name__.upper(),
            ' '.join([str(param) for param in params]),
            e
        )


def _update_redis(pipe, data, user):
    now = int(time.time())
    taxi_id = data['taxi_id']
    operator = user.email
    # Hardcoded for backwards compatibility with the geotaxi worker
    timestamp = now
    # These fields are unused, fill them with whatever is expected
    status = 'free'  # light status, the actual status is read from VehicleDescription
    device = 'phone'
    version = 2

    # HSET taxi:<id>
    _run_redis_action(
        pipe,
        'HSET',
        f"taxi:{taxi_id}",
        operator,
        f"{timestamp} {data['lat']} {data['lon']} {status} {device} {version}",
    )
    # GEOADD geoindex
    _run_redis_action(
        pipe,
        'GEOADD',
        'geoindex',
        [data['lon'], data['lat'], taxi_id],
    )
    # GEOADD geoindex_2
    _run_redis_action(
        pipe,
        'GEOADD',
        'geoindex_2',
        [data['lon'], data['lat'], f"{taxi_id}:{operator}"],
    )
    # ZADD timestamps
    _run_redis_action(
        pipe,
        'ZADD',
        'timestamps',
        {f"{taxi_id}:{operator}": now},
    )
    # ZADD timestamps_id
    _run_redis_action(
        pipe,
        'ZADD',
        'timestamps_id',
        {taxi_id: now},
    )


@blueprint.route('/geotaxi/', methods=['POST'])
@login_required
@roles_accepted('admin', 'operateur')
def geotaxi_batch():
    """
    ---
    post:
        description: Update the position of many taxis
        requestBody:
            content:
                application/json:
                    schema: DataGeotaxiSchema
        security:
            - ApiKeyAuth: []
        responses:
            200:
                description: All the taxi positions were updated
    """
    schema = schemas.DataGeotaxiSchema()<commit_msg>geotaxi: better description<commit_after>import socket
import time

from flask import Blueprint, current_app, request
from flask_security import current_user, login_required, roles_accepted
import redis

from APITaxi_models2 import db, Taxi, Vehicle, VehicleDescription

from .. import schemas
from ..validators import (
    make_error_json_response,
    validate_schema
)


blueprint = Blueprint('geotaxi', __name__)


def _run_redis_action(pipe, action, *params):
    action = getattr(pipe, action.lower())

    # Run action
    try:
        action(*params)
    except socket.error:
        current_app.logger.error(
            'Error while running redis action %s %s',
            action.__name__.upper(),
            ' '.join([str(param) for param in params])
        )
    except redis.RedisError as e:
        current_app.logger.error(
            'Error while running redis action %s %s %s',
            action.__name__.upper(),
            ' '.join([str(param) for param in params]),
            e
        )


def _update_redis(pipe, data, user):
    now = int(time.time())
    taxi_id = data['taxi_id']
    operator = user.email
    # Hardcoded for backwards compatibility with the geotaxi worker
    timestamp = now
    # These fields are unused, fill them with whatever is expected
    status = 'free'  # light status, the actual status is read from VehicleDescription
    device = 'phone'
    version = 2

    # HSET taxi:<id>
    _run_redis_action(
        pipe,
        'HSET',
        f"taxi:{taxi_id}",
        operator,
        f"{timestamp} {data['lat']} {data['lon']} {status} {device} {version}",
    )
    # GEOADD geoindex
    _run_redis_action(
        pipe,
        'GEOADD',
        'geoindex',
        [data['lon'], data['lat'], taxi_id],
    )
    # GEOADD geoindex_2
    _run_redis_action(
        pipe,
        'GEOADD',
        'geoindex_2',
        [data['lon'], data['lat'], f"{taxi_id}:{operator}"],
    )
    # ZADD timestamps
    _run_redis_action(
        pipe,
        'ZADD',
        'timestamps',
        {f"{taxi_id}:{operator}": now},
    )
    # ZADD timestamps_id
    _run_redis_action(
        pipe,
        'ZADD',
        'timestamps_id',
        {taxi_id: now},
    )


@blueprint.route('/geotaxi/', methods=['POST'])
@login_required
@roles_accepted('admin', 'operateur')
def geotaxi_batch():
    """
    ---
    post:
        description: |
            Update the position of many taxis at once (up to 50).

            All data must be valid or the whole request will be rejected.

            Positions are in the WGS 84 or EPSG:3857 standard (the same as GPS).
        requestBody:
            content:
                application/json:
                    schema: DataGeotaxiSchema
        security:
            - ApiKeyAuth: []
        responses:
            200:
                description: All the taxi positions were updated
    """
    schema = schemas.DataGeotaxiSchema()
{'fraction_non_alphanumeric': 0.10995227152200814, 'fraction_numerical': 0.003888987095633728, 'mean_word_length': 2.2202618099032443, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '324451', 'n_tokens_mistral': 1780, 'n_tokens_neox': 1736, 'n_words': 447}