# -*- coding: utf-8 -*-
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import dataclasses
import json  # type: ignore
import re
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
import warnings

from google.api_core import (
    gapic_v1,
    operations_v1,
    path_template,
    rest_helpers,
    rest_streaming,
)
from google.api_core import exceptions as core_exceptions
from google.api_core import retry as retries
from google.auth import credentials as ga_credentials  # type: ignore
from google.auth.transport.grpc import SslCredentials  # type: ignore
from google.auth.transport.requests import AuthorizedSession  # type: ignore
from google.protobuf import json_format
import grpc  # type: ignore
from requests import __version__ as requests_version

try:
    OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
except AttributeError:  # pragma: NO COVER
    OptionalRetry = Union[retries.Retry, object]  # type: ignore

from google.longrunning import operations_pb2  # type: ignore

from google.analytics.data_v1alpha.types import analytics_data_api

from .base import AlphaAnalyticsDataTransport
from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO

DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
    gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
    grpc_version=None,
    rest_version=requests_version,
)

class AlphaAnalyticsDataRestInterceptor:
    """Interceptor for AlphaAnalyticsData.

    Interceptors are used to manipulate requests, request metadata, and responses
    in arbitrary ways.
    Example use cases include:
    * Logging
    * Verifying requests according to service or custom semantics
    * Stripping extraneous information from responses

    These use cases and more can be enabled by injecting an
    instance of a custom subclass when constructing the AlphaAnalyticsDataRestTransport.

    .. code-block:: python
        class MyCustomAlphaAnalyticsDataInterceptor(AlphaAnalyticsDataRestInterceptor):
            def pre_create_audience_list(self, request, metadata):
                logging.log(f"Received request: {request}")
                return request, metadata

            def post_create_audience_list(self, response):
                logging.log(f"Received response: {response}")
                return response

            def pre_get_audience_list(self, request, metadata):
                logging.log(f"Received request: {request}")
                return request, metadata

            def post_get_audience_list(self, response):
                logging.log(f"Received response: {response}")
                return response

            def pre_list_audience_lists(self, request, metadata):
                logging.log(f"Received request: {request}")
                return request, metadata

            def post_list_audience_lists(self, response):
                logging.log(f"Received response: {response}")
                return response

            def pre_query_audience_list(self, request, metadata):
                logging.log(f"Received request: {request}")
                return request, metadata

            def post_query_audience_list(self, response):
                logging.log(f"Received response: {response}")
                return response

            def pre_run_funnel_report(self, request, metadata):
                logging.log(f"Received request: {request}")
                return request, metadata

            def post_run_funnel_report(self, response):
                logging.log(f"Received response: {response}")
                return response

        transport = AlphaAnalyticsDataRestTransport(interceptor=MyCustomAlphaAnalyticsDataInterceptor())
        client = AlphaAnalyticsDataClient(transport=transport)

    """

    def pre_create_audience_list(
        self,
        request: analytics_data_api.CreateAudienceListRequest,
        metadata: Sequence[Tuple[str, str]],
    ) -> Tuple[analytics_data_api.CreateAudienceListRequest, Sequence[Tuple[str, str]]]:
        """Pre-rpc interceptor for create_audience_list

        Override in a subclass to manipulate the request or metadata
        before they are sent to the AlphaAnalyticsData server.
        """
        return request, metadata

    def post_create_audience_list(
        self, response: operations_pb2.Operation
    ) -> operations_pb2.Operation:
        """Post-rpc interceptor for create_audience_list

        Override in a subclass to manipulate the response
        after it is returned by the AlphaAnalyticsData server but before
        it is returned to user code.
        """
        return response

    def pre_get_audience_list(
        self,
        request: analytics_data_api.GetAudienceListRequest,
        metadata: Sequence[Tuple[str, str]],
    ) -> Tuple[analytics_data_api.GetAudienceListRequest, Sequence[Tuple[str, str]]]:
        """Pre-rpc interceptor for get_audience_list

        Override in a subclass to manipulate the request or metadata
        before they are sent to the AlphaAnalyticsData server.
        """
        return request, metadata

    def post_get_audience_list(
        self, response: analytics_data_api.AudienceList
    ) -> analytics_data_api.AudienceList:
        """Post-rpc interceptor for get_audience_list

        Override in a subclass to manipulate the response
        after it is returned by the AlphaAnalyticsData server but before
        it is returned to user code.
        """
        return response

    def pre_list_audience_lists(
        self,
        request: analytics_data_api.ListAudienceListsRequest,
        metadata: Sequence[Tuple[str, str]],
    ) -> Tuple[analytics_data_api.ListAudienceListsRequest, Sequence[Tuple[str, str]]]:
        """Pre-rpc interceptor for list_audience_lists

        Override in a subclass to manipulate the request or metadata
        before they are sent to the AlphaAnalyticsData server.
        """
        return request, metadata

    def post_list_audience_lists(
        self, response: analytics_data_api.ListAudienceListsResponse
    ) -> analytics_data_api.ListAudienceListsResponse:
        """Post-rpc interceptor for list_audience_lists

        Override in a subclass to manipulate the response
        after it is returned by the AlphaAnalyticsData server but before
        it is returned to user code.
        """
        return response

    def pre_query_audience_list(
        self,
        request: analytics_data_api.QueryAudienceListRequest,
        metadata: Sequence[Tuple[str, str]],
    ) -> Tuple[analytics_data_api.QueryAudienceListRequest, Sequence[Tuple[str, str]]]:
        """Pre-rpc interceptor for query_audience_list

        Override in a subclass to manipulate the request or metadata
        before they are sent to the AlphaAnalyticsData server.
        """
        return request, metadata

    def post_query_audience_list(
        self, response: analytics_data_api.QueryAudienceListResponse
    ) -> analytics_data_api.QueryAudienceListResponse:
        """Post-rpc interceptor for query_audience_list

        Override in a subclass to manipulate the response
        after it is returned by the AlphaAnalyticsData server but before
        it is returned to user code.
        """
        return response

    def pre_run_funnel_report(
        self,
        request: analytics_data_api.RunFunnelReportRequest,
        metadata: Sequence[Tuple[str, str]],
    ) -> Tuple[analytics_data_api.RunFunnelReportRequest, Sequence[Tuple[str, str]]]:
        """Pre-rpc interceptor for run_funnel_report

        Override in a subclass to manipulate the request or metadata
        before they are sent to the AlphaAnalyticsData server.
        """
        return request, metadata

    def post_run_funnel_report(
        self, response: analytics_data_api.RunFunnelReportResponse
    ) -> analytics_data_api.RunFunnelReportResponse:
        """Post-rpc interceptor for run_funnel_report

        Override in a subclass to manipulate the response
        after it is returned by the AlphaAnalyticsData server but before
        it is returned to user code.
        """
        return response

@dataclasses.dataclass
class AlphaAnalyticsDataRestStub:
    _session: AuthorizedSession
    _host: str
    _interceptor: AlphaAnalyticsDataRestInterceptor

class AlphaAnalyticsDataRestTransport(AlphaAnalyticsDataTransport):
    """REST backend transport for AlphaAnalyticsData.

    Google Analytics reporting data service.

    This class defines the same methods as the primary client, so the
    primary client can load the underlying transport implementation
    and call it.

    It sends JSON representations of protocol buffers over HTTP/1.1

    """

    def __init__(
        self,
        *,
        host: str = "analyticsdata.googleapis.com",
        credentials: Optional[ga_credentials.Credentials] = None,
        credentials_file: Optional[str] = None,
        scopes: Optional[Sequence[str]] = None,
        client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
        quota_project_id: Optional[str] = None,
        client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
        always_use_jwt_access: Optional[bool] = False,
        url_scheme: str = "https",
        interceptor: Optional[AlphaAnalyticsDataRestInterceptor] = None,
        api_audience: Optional[str] = None,
    ) -> None:
        """Instantiate the transport.

        Args:
            host (Optional[str]):
                 The hostname to connect to.
            credentials (Optional[google.auth.credentials.Credentials]): The
                authorization credentials to attach to requests. These
                credentials identify the application to the service; if none
                are specified, the client will attempt to ascertain the
                credentials from the environment.

            credentials_file (Optional[str]): A file with credentials that can
                be loaded with :func:`google.auth.load_credentials_from_file`.
                This argument is ignored if ``channel`` is provided.
            scopes (Optional(Sequence[str])): A list of scopes. This argument is
                ignored if ``channel`` is provided.
            client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
                certificate to configure mutual TLS HTTP channel. It is ignored
                if ``channel`` is provided.
            quota_project_id (Optional[str]): An optional project to use for billing
                and quota.
            client_info (google.api_core.gapic_v1.client_info.ClientInfo):
                The client info used to send a user-agent string along with
                API requests. If ``None``, then default info will be used.
                Generally, you only need to set this if you are developing
                your own client library.
            always_use_jwt_access (Optional[bool]): Whether self signed JWT should
                be used for service account credentials.
            url_scheme: the protocol scheme for the API endpoint.  Normally
                "https", but for testing or local servers,
                "http" can be specified.
        """
        # Run the base constructor
        # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
        # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
        # credentials object
        maybe_url_match = re.match("^(?P<scheme>http(?:s)?://)?(?P<host>.*)$", host)
        if maybe_url_match is None:
            raise ValueError(
                f"Unexpected hostname structure: {host}"
            )  # pragma: NO COVER

        url_match_items = maybe_url_match.groupdict()

        host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host

        super().__init__(
            host=host,
            credentials=credentials,
            client_info=client_info,
            always_use_jwt_access=always_use_jwt_access,
            api_audience=api_audience,
        )
        self._session = AuthorizedSession(
            self._credentials, default_host=self.DEFAULT_HOST
        )
        self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None
        if client_cert_source_for_mtls:
            self._session.configure_mtls_channel(client_cert_source_for_mtls)
        self._interceptor = interceptor or AlphaAnalyticsDataRestInterceptor()
        self._prep_wrapped_messages(client_info)

    @property
    def operations_client(self) -> operations_v1.AbstractOperationsClient:
        """Create the client designed to process long-running operations.

        This property caches on the instance; repeated calls return the same
        client.
        """
        # Only create a new client if we do not already have one.
        if self._operations_client is None:
            http_options: Dict[str, List[Dict[str, str]]] = {}

            rest_transport = operations_v1.OperationsRestTransport(
                host=self._host,
                # use the credentials which are saved
                credentials=self._credentials,
                scopes=self._scopes,
                http_options=http_options,
                path_prefix="v1alpha",
            )

            self._operations_client = operations_v1.AbstractOperationsClient(
                transport=rest_transport
            )

        # Return the client from cache.
        return self._operations_client

    class _CreateAudienceList(AlphaAnalyticsDataRestStub):
        def __hash__(self):
            return hash("CreateAudienceList")

        __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}

        @classmethod
        def _get_unset_required_fields(cls, message_dict):
            return {
                k: v
                for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
                if k not in message_dict
            }

        def __call__(
            self,
            request: analytics_data_api.CreateAudienceListRequest,
            *,
            retry: OptionalRetry = gapic_v1.method.DEFAULT,
            timeout: Optional[float] = None,
            metadata: Sequence[Tuple[str, str]] = (),
        ) -> operations_pb2.Operation:
            r"""Call the create audience list method over HTTP.

            Args:
                request (~.analytics_data_api.CreateAudienceListRequest):
                    The request object. A request to create a new audience
                list.
                retry (google.api_core.retry.Retry): Designation of what errors, if any,
                    should be retried.
                timeout (float): The timeout for this request.
                metadata (Sequence[Tuple[str, str]]): Strings which should be
                    sent along with the request as metadata.

            Returns:
                ~.operations_pb2.Operation:
                    This resource represents a
                long-running operation that is the
                result of a network API call.

            """

            http_options: List[Dict[str, str]] = [
                {
                    "method": "post",
                    "uri": "/v1alpha/{parent=properties/*}/audienceLists",
                    "body": "audience_list",
                },
            ]
            request, metadata = self._interceptor.pre_create_audience_list(
                request, metadata
            )
            pb_request = analytics_data_api.CreateAudienceListRequest.pb(request)
            transcoded_request = path_template.transcode(http_options, pb_request)

            # Jsonify the request body

            body = json_format.MessageToJson(
                transcoded_request["body"],
                including_default_value_fields=False,
                use_integers_for_enums=True,
            )
            uri = transcoded_request["uri"]
            method = transcoded_request["method"]

            # Jsonify the query params
            query_params = json.loads(
                json_format.MessageToJson(
                    transcoded_request["query_params"],
                    including_default_value_fields=False,
                    use_integers_for_enums=True,
                )
            )
            query_params.update(self._get_unset_required_fields(query_params))

            query_params["$alt"] = "json;enum-encoding=int"

            # Send the request
            headers = dict(metadata)
            headers["Content-Type"] = "application/json"
            response = getattr(self._session, method)(
                "{host}{uri}".format(host=self._host, uri=uri),
                timeout=timeout,
                headers=headers,
                params=rest_helpers.flatten_query_params(query_params, strict=True),
                data=body,
            )

            # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
            # subclass.
            if response.status_code >= 400:
                raise core_exceptions.from_http_response(response)

            # Return the response
            resp = operations_pb2.Operation()
            json_format.Parse(response.content, resp, ignore_unknown_fields=True)
            resp = self._interceptor.post_create_audience_list(resp)
            return resp

    class _GetAudienceList(AlphaAnalyticsDataRestStub):
        def __hash__(self):
            return hash("GetAudienceList")

        __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}

        @classmethod
        def _get_unset_required_fields(cls, message_dict):
            return {
                k: v
                for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
                if k not in message_dict
            }

        def __call__(
            self,
            request: analytics_data_api.GetAudienceListRequest,
            *,
            retry: OptionalRetry = gapic_v1.method.DEFAULT,
            timeout: Optional[float] = None,
            metadata: Sequence[Tuple[str, str]] = (),
        ) -> analytics_data_api.AudienceList:
            r"""Call the get audience list method over HTTP.

            Args:
                request (~.analytics_data_api.GetAudienceListRequest):
                    The request object. A request to retrieve configuration
                metadata about a specific audience list.
                retry (google.api_core.retry.Retry): Designation of what errors, if any,
                    should be retried.
                timeout (float): The timeout for this request.
                metadata (Sequence[Tuple[str, str]]): Strings which should be
                    sent along with the request as metadata.

            Returns:
                ~.analytics_data_api.AudienceList:
                    An audience list is a list of users
                in an audience at the time of the list's
                creation. One audience may have multiple
                audience lists created for different
                days.

            """

            http_options: List[Dict[str, str]] = [
                {
                    "method": "get",
                    "uri": "/v1alpha/{name=properties/*/audienceLists/*}",
                },
            ]
            request, metadata = self._interceptor.pre_get_audience_list(
                request, metadata
            )
            pb_request = analytics_data_api.GetAudienceListRequest.pb(request)
            transcoded_request = path_template.transcode(http_options, pb_request)

            uri = transcoded_request["uri"]
            method = transcoded_request["method"]

            # Jsonify the query params
            query_params = json.loads(
                json_format.MessageToJson(
                    transcoded_request["query_params"],
                    including_default_value_fields=False,
                    use_integers_for_enums=True,
                )
            )
            query_params.update(self._get_unset_required_fields(query_params))

            query_params["$alt"] = "json;enum-encoding=int"

            # Send the request
            headers = dict(metadata)
            headers["Content-Type"] = "application/json"
            response = getattr(self._session, method)(
                "{host}{uri}".format(host=self._host, uri=uri),
                timeout=timeout,
                headers=headers,
                params=rest_helpers.flatten_query_params(query_params, strict=True),
            )

            # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
            # subclass.
            if response.status_code >= 400:
                raise core_exceptions.from_http_response(response)

            # Return the response
            resp = analytics_data_api.AudienceList()
            pb_resp = analytics_data_api.AudienceList.pb(resp)

            json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
            resp = self._interceptor.post_get_audience_list(resp)
            return resp

    class _ListAudienceLists(AlphaAnalyticsDataRestStub):
        def __hash__(self):
            return hash("ListAudienceLists")

        __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}

        @classmethod
        def _get_unset_required_fields(cls, message_dict):
            return {
                k: v
                for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
                if k not in message_dict
            }

        def __call__(
            self,
            request: analytics_data_api.ListAudienceListsRequest,
            *,
            retry: OptionalRetry = gapic_v1.method.DEFAULT,
            timeout: Optional[float] = None,
            metadata: Sequence[Tuple[str, str]] = (),
        ) -> analytics_data_api.ListAudienceListsResponse:
            r"""Call the list audience lists method over HTTP.

            Args:
                request (~.analytics_data_api.ListAudienceListsRequest):
                    The request object. A request to list all audience lists
                for a property.
                retry (google.api_core.retry.Retry): Designation of what errors, if any,
                    should be retried.
                timeout (float): The timeout for this request.
                metadata (Sequence[Tuple[str, str]]): Strings which should be
                    sent along with the request as metadata.

            Returns:
                ~.analytics_data_api.ListAudienceListsResponse:
                    A list of all audience lists for a
                property.

            """

            http_options: List[Dict[str, str]] = [
                {
                    "method": "get",
                    "uri": "/v1alpha/{parent=properties/*}/audienceLists",
                },
            ]
            request, metadata = self._interceptor.pre_list_audience_lists(
                request, metadata
            )
            pb_request = analytics_data_api.ListAudienceListsRequest.pb(request)
            transcoded_request = path_template.transcode(http_options, pb_request)

            uri = transcoded_request["uri"]
            method = transcoded_request["method"]

            # Jsonify the query params
            query_params = json.loads(
                json_format.MessageToJson(
                    transcoded_request["query_params"],
                    including_default_value_fields=False,
                    use_integers_for_enums=True,
                )
            )
            query_params.update(self._get_unset_required_fields(query_params))

            query_params["$alt"] = "json;enum-encoding=int"

            # Send the request
            headers = dict(metadata)
            headers["Content-Type"] = "application/json"
            response = getattr(self._session, method)(
                "{host}{uri}".format(host=self._host, uri=uri),
                timeout=timeout,
                headers=headers,
                params=rest_helpers.flatten_query_params(query_params, strict=True),
            )

            # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
            # subclass.
            if response.status_code >= 400:
                raise core_exceptions.from_http_response(response)

            # Return the response
            resp = analytics_data_api.ListAudienceListsResponse()
            pb_resp = analytics_data_api.ListAudienceListsResponse.pb(resp)

            json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
            resp = self._interceptor.post_list_audience_lists(resp)
            return resp

    class _QueryAudienceList(AlphaAnalyticsDataRestStub):
        def __hash__(self):
            return hash("QueryAudienceList")

        def __call__(
            self,
            request: analytics_data_api.QueryAudienceListRequest,
            *,
            retry: OptionalRetry = gapic_v1.method.DEFAULT,
            timeout: Optional[float] = None,
            metadata: Sequence[Tuple[str, str]] = (),
        ) -> analytics_data_api.QueryAudienceListResponse:
            r"""Call the query audience list method over HTTP.

            Args:
                request (~.analytics_data_api.QueryAudienceListRequest):
                    The request object. A request to list users in an
                audience list.
                retry (google.api_core.retry.Retry): Designation of what errors, if any,
                    should be retried.
                timeout (float): The timeout for this request.
                metadata (Sequence[Tuple[str, str]]): Strings which should be
                    sent along with the request as metadata.

            Returns:
                ~.analytics_data_api.QueryAudienceListResponse:
                    A list of users in an audience list.
            """

            http_options: List[Dict[str, str]] = [
                {
                    "method": "post",
                    "uri": "/v1alpha/{name=properties/*/audienceLists/*}:query",
                    "body": "*",
                },
            ]
            request, metadata = self._interceptor.pre_query_audience_list(
                request, metadata
            )
            pb_request = analytics_data_api.QueryAudienceListRequest.pb(request)
            transcoded_request = path_template.transcode(http_options, pb_request)

            # Jsonify the request body

            body = json_format.MessageToJson(
                transcoded_request["body"],
                including_default_value_fields=False,
                use_integers_for_enums=True,
            )
            uri = transcoded_request["uri"]
            method = transcoded_request["method"]

            # Jsonify the query params
            query_params = json.loads(
                json_format.MessageToJson(
                    transcoded_request["query_params"],
                    including_default_value_fields=False,
                    use_integers_for_enums=True,
                )
            )

            query_params["$alt"] = "json;enum-encoding=int"

            # Send the request
            headers = dict(metadata)
            headers["Content-Type"] = "application/json"
            response = getattr(self._session, method)(
                "{host}{uri}".format(host=self._host, uri=uri),
                timeout=timeout,
                headers=headers,
                params=rest_helpers.flatten_query_params(query_params, strict=True),
                data=body,
            )

            # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
            # subclass.
            if response.status_code >= 400:
                raise core_exceptions.from_http_response(response)

            # Return the response
            resp = analytics_data_api.QueryAudienceListResponse()
            pb_resp = analytics_data_api.QueryAudienceListResponse.pb(resp)

            json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
            resp = self._interceptor.post_query_audience_list(resp)
            return resp

    class _RunFunnelReport(AlphaAnalyticsDataRestStub):
        def __hash__(self):
            return hash("RunFunnelReport")

        def __call__(
            self,
            request: analytics_data_api.RunFunnelReportRequest,
            *,
            retry: OptionalRetry = gapic_v1.method.DEFAULT,
            timeout: Optional[float] = None,
            metadata: Sequence[Tuple[str, str]] = (),
        ) -> analytics_data_api.RunFunnelReportResponse:
            r"""Call the run funnel report method over HTTP.

            Args:
                request (~.analytics_data_api.RunFunnelReportRequest):
                    The request object. The request for a funnel report.
                retry (google.api_core.retry.Retry): Designation of what errors, if any,
                    should be retried.
                timeout (float): The timeout for this request.
                metadata (Sequence[Tuple[str, str]]): Strings which should be
                    sent along with the request as metadata.

            Returns:
                ~.analytics_data_api.RunFunnelReportResponse:
                    The funnel report response contains
                two sub reports. The two sub reports are
                different combinations of dimensions and
                metrics.

            """

            http_options: List[Dict[str, str]] = [
                {
                    "method": "post",
                    "uri": "/v1alpha/{property=properties/*}:runFunnelReport",
                    "body": "*",
                },
            ]
            request, metadata = self._interceptor.pre_run_funnel_report(
                request, metadata
            )
            pb_request = analytics_data_api.RunFunnelReportRequest.pb(request)
            transcoded_request = path_template.transcode(http_options, pb_request)

            # Jsonify the request body

            body = json_format.MessageToJson(
                transcoded_request["body"],
                including_default_value_fields=False,
                use_integers_for_enums=True,
            )
            uri = transcoded_request["uri"]
            method = transcoded_request["method"]

            # Jsonify the query params
            query_params = json.loads(
                json_format.MessageToJson(
                    transcoded_request["query_params"],
                    including_default_value_fields=False,
                    use_integers_for_enums=True,
                )
            )

            query_params["$alt"] = "json;enum-encoding=int"

            # Send the request
            headers = dict(metadata)
            headers["Content-Type"] = "application/json"
            response = getattr(self._session, method)(
                "{host}{uri}".format(host=self._host, uri=uri),
                timeout=timeout,
                headers=headers,
                params=rest_helpers.flatten_query_params(query_params, strict=True),
                data=body,
            )

            # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
            # subclass.
            if response.status_code >= 400:
                raise core_exceptions.from_http_response(response)

            # Return the response
            resp = analytics_data_api.RunFunnelReportResponse()
            pb_resp = analytics_data_api.RunFunnelReportResponse.pb(resp)

            json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
            resp = self._interceptor.post_run_funnel_report(resp)
            return resp

    @property
    def create_audience_list(
        self,
    ) -> Callable[
        [analytics_data_api.CreateAudienceListRequest], operations_pb2.Operation
    ]:
        # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
        # In C++ this would require a dynamic_cast
        return self._CreateAudienceList(self._session, self._host, self._interceptor)  # type: ignore

    @property
    def get_audience_list(
        self,
    ) -> Callable[
        [analytics_data_api.GetAudienceListRequest], analytics_data_api.AudienceList
    ]:
        # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
        # In C++ this would require a dynamic_cast
        return self._GetAudienceList(self._session, self._host, self._interceptor)  # type: ignore

    @property
    def list_audience_lists(
        self,
    ) -> Callable[
        [analytics_data_api.ListAudienceListsRequest],
        analytics_data_api.ListAudienceListsResponse,
    ]:
        # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
        # In C++ this would require a dynamic_cast
        return self._ListAudienceLists(self._session, self._host, self._interceptor)  # type: ignore

    @property
    def query_audience_list(
        self,
    ) -> Callable[
        [analytics_data_api.QueryAudienceListRequest],
        analytics_data_api.QueryAudienceListResponse,
    ]:
        # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
        # In C++ this would require a dynamic_cast
        return self._QueryAudienceList(self._session, self._host, self._interceptor)  # type: ignore

    @property
    def run_funnel_report(
        self,
    ) -> Callable[
        [analytics_data_api.RunFunnelReportRequest],
        analytics_data_api.RunFunnelReportResponse,
    ]:
        # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
        # In C++ this would require a dynamic_cast
        return self._RunFunnelReport(self._session, self._host, self._interceptor)  # type: ignore

    @property
    def kind(self) -> str:
        return "rest"

    def close(self):
        self._session.close()

__all__ = ("AlphaAnalyticsDataRestTransport",)


# Copyright 2014, Sandia Corporation. Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain
# rights in this software.

from behave import *
import nose.tools

import glob
import logging
import os
import pkgutil
import shutil
import subprocess
import sys

import IPython
import IPython.core.interactiveshell
import nbformat

import toyplot

log = logging.getLogger(__name__)
log.name = "features.steps.documentation"

root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
docs_dir = os.path.join(root_dir, "docs")
package_dir = os.path.join(root_dir, "toyplot")

@given(u'all public Toyplot modules')
def step_impl(context):
    def walk_modules(package, path):
        modules = []
        modules.append(package)
        for loader, name, is_package in pkgutil.iter_modules([path]):
            modules += walk_modules(package + "." + name, os.path.join(path, name))
        return modules
    context.modules = sorted(walk_modules("toyplot", package_dir))

@given(u'the Toyplot reference documentation')
def step_impl(context):
    context.references = []
    for directory, subdirectories, filenames in os.walk(docs_dir):
        if os.path.basename(directory) in ["js"]:
            continue
        for filename in filenames:
            if os.path.splitext(filename)[1] not in [".rst"]:
                continue
            if not filename.startswith("toyplot."):
                continue

            context.references.append(os.path.join(directory, filename))
    context.references = sorted(context.references)

@then(u'every module must have a section in the reference documentation')
def step_impl(context):
    for module in context.modules:
        if os.path.join(docs_dir, module + ".rst") not in context.references:
            raise AssertionError("No matching documentation found for the %s module." % module)

@then(u'every section in the reference documentation must match a module')
def step_impl(context):
    modules = [os.path.join(docs_dir, module + ".rst") for module in context.modules]
    for reference in context.references:
        if reference not in modules:
            raise AssertionError("No matching module found for %s." % reference)

@given(u'the Toyplot documentation notebooks')
def step_impl(context):
    context.notebooks = sorted(glob.glob(os.path.join(docs_dir, "*.ipynb")))

@then(u'every notebook runs without error')
def step_impl(context):
    sys.path.append(docs_dir)
    cwd = os.getcwd()
    os.chdir(docs_dir)
    for notebook in context.notebooks:
        context.execute_steps(u"Then notebook %s runs without error" % notebook)
    os.chdir(cwd)
    sys.path.remove(docs_dir)

@then(u'notebook {notebook} runs without error')
def step_impl(context, notebook):
    log.info(notebook)

    with open(notebook) as stream:
        notebook = nbformat.read(stream, as_version=4)

    shell = IPython.core.interactiveshell.InteractiveShell.instance()
    nblocals = dict()

    for cell in notebook.cells:
        if cell.cell_type == "code":
            code = shell.input_transformer_manager.transform_cell(cell.source)
            exec(code, nblocals)
            toyplot.Canvas._ipython_post_execute()

#    # Run each notebook script, keeping track of failures.
#    failures = {}
#    for notebook, script in zip(context.notebooks, context.scripts):
#        try:
#            command = ["coverage", "run", "--source", "toyplot", "--append", script]
#            log.info(" ".join(command))
#            subprocess.check_call(command, cwd=docs_dir)
#            # Remove the script (we only do this if execution succeeded)
#            os.remove(script)
#        except Exception as e:
#            failures[notebook] = e
#
#    if failures:
#        message = ""
#        for notebook_path, exception in failures.items():
#            message += notebook_path + " exception:\n\n" + exception + "\n\n"
#        raise AssertionError(message)


count=1
count1=1

print("Type a value of 'N' you want to print up to, ( Eg: 30 ) otherwise simply press enter to make default ( N=17 )")
print("")
print("N = ",end='')
y=input()
print("")

if y!="":
    N=int(y)
else:
    N=18

for n in range(1,N):
       if n == 3 * count and n == 5 * count1:
           print("FizzBuzz,", end='')
           count+=1
           count1+=1
       elif n==3*count:
           print("Fizz,",end='')
           count+=1
       elif n==5*count1:
           print("Buzz,",end='')
           count1+=1
       else:
           print(str(n)+',',end='')
print("")
print("")
print("Press enter to exit the program")
input()


# it makes easy to filter data from iterables

# list

# l = [1, 2, 3, 4, 5, 45, 65, 6, 64]

# result = list(filter(lambda x: x % 2 == 0, l))
# print(result)

# dictionary
d = {'1': 20, '2': 31, '3': 40}

# x[0] : keys of dictionary, x[1] : values of dictionary
result = dict(filter(lambda x: x[1] % 2 == 0, d.items()))
print(result)


import cv2
import numpy as np

if __name__ == '__main__':
    def nothing(*arg):
        pass

cv2.namedWindow( "result" ) # создаем главное окно
cv2.namedWindow( "settings" ) # создаем окно настроек

# создаем 6 бегунков для настройки начального и конечного цвета фильтра
cv2.createTrackbar('h1', 'settings', 0, 255, nothing)
cv2.createTrackbar('l1', 'settings', 0, 255, nothing)
cv2.createTrackbar('s1', 'settings', 0, 255, nothing)
cv2.createTrackbar('h2', 'settings', 255, 255, nothing)
cv2.createTrackbar('l2', 'settings', 255, 255, nothing)
cv2.createTrackbar('s2', 'settings', 255, 255, nothing)
crange = [0,0,0, 0,0,0]

while True:
    img = cv2.imread("way.jpg")
    hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS )

    # считываем значения бегунков
    h1 = cv2.getTrackbarPos('h1', 'settings')
    l1 = cv2.getTrackbarPos('l1', 'settings')
    s1 = cv2.getTrackbarPos('s1', 'settings')
    h2 = cv2.getTrackbarPos('h2', 'settings')
    l2 = cv2.getTrackbarPos('l2', 'settings')
    s2 = cv2.getTrackbarPos('s2', 'settings')

    # формируем начальный и конечный цвет фильтра
    h_min = np.array((h1, l1, s1), np.uint8)
    h_max = np.array((h2, l2, s2), np.uint8)

    # накладываем фильтр на кадр в модели HSV
    thresh = cv2.inRange(hls, h_min, h_max)
    res = cv2.bitwise_and(img,img, mask= thresh)
    """
    cv2.imshow("res.jpg",res)
    low_threshold = 50
    high_threshold = 150
    edges = cv2.Canny(res, low_threshold, high_threshold)
    rho = 1  # distance resolution in pixels of the Hough grid
    theta = np.pi / 180  # angular resolution in radians of the Hough grid
    threshold = 15  # minimum number of votes (intersections in Hough grid cell)
    min_line_length = 100  # minimum number of pixels making up a line
    max_line_gap = 5
    line_image = np.copy(img) * 0
    lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
                    min_line_length, max_line_gap)
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(line_image,(x1,y1),(x2,y2),(0,255,0),5)

    lines_edges = cv2.addWeighted(img, 0.8, line_image, 1, 0)

    #cv2.imwrite("ou.jpg",lines_edges)
	"""
    cv2.imshow('result', res)

    ch = cv2.waitKey(5)
    if ch == 27:
        break


"""hrkmusic URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from hrkapp.views import ArtistaViewSet, AlbumViewSet, CancionViewSet, TipomusicaViewSet, CatalogoViewSet, UsuarioViewSet, PlaylistViewSet

router = routers.DefaultRouter()
# router.register(r'users', views.UserViewSet)
# router.register(r'groups', views.GroupViewSet)

router.register(r'artista', ArtistaViewSet, basename = 'artista')
router.register(r'album', AlbumViewSet, basename = 'album')
router.register(r'cancion', CancionViewSet, basename = 'cancion')
router.register(r'tipomusica', TipomusicaViewSet, basename = 'tipomusica')
router.register(r'catalogo', CatalogoViewSet, basename = 'catalogo')
router.register(r'usuario', UsuarioViewSet, basename = 'usuario')
router.register(r'playlist', PlaylistViewSet, basename = 'playlist')

urlpatterns = [
   path('', include(router.urls)),
   path('admin/', admin.site.urls),
   # path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]


from flask import Flask, render_template, request, redirect, url_for, flash
from flask_mysqldb import MySQL

app = Flask(__name__)

#Mysql Connection
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'John_20'
app.config['MYSQL_DB'] = 'flaskformulario'
mysql = MySQL(app)

# settings
app.secret_key ='mysecretkey'

# cambios para la tabla
@app.route('/')
def Index():
      cur = mysql.connection.cursor()
      cur.execute('SELECT * FROM eval')
      data = cur.fetchall()
      return render_template('index.html', eval = data)

@app.route('/add_contact', methods=['POST'])
def add_contact():
    if request.method == 'POST':
        fullname = request.form['fullname']
        phone = request.form['phone']
        email = request.form['email']
        num1 = request.form['num1']
        num2 = request.form['num2']
        num3 = request.form['num3']
        num4 = request.form['num4']
        num5 = request.form['num5']
        num6 = request.form['num6']
        cur = mysql.connection.cursor()
        cur.execute("INSERT INTO eval (fullname, phone, email, num1, num2, num3, num4, num5, num6) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)", (fullname, phone, email, num1, num2, num3, num4, num5, num6))
        mysql.connection.commit()
        flash('Contact Added successfully')
        return redirect(url_for('Index'))

@app.route('/edit/<id>')
def get_contact(id):
    cur = mysql.connection.cursor()
    cur.execute('SELECT * FROM eval WHERE id = %s', (id))
    data = cur.fetchall()
    return render_template('edit-for.html', contact = data[0])

@app.route('/update/<id>', methods = ['POST'])
def update_contact(id):
    if request.method == 'POST':
        fullname = request.form['fullname']
        phone = request.form['phone']
        email = request.form['email']
        num1 = request.form['num1']
        num2 = request.form['num2']
        num3 = request.form['num3']
        num4 = request.form['num4']
        num5 = request.form['num5']
        num6 = request.form['num6']
        cur = mysql.connection.cursor()
        cur.execute("""
            UPDATE eval
            SET fullname = %s,
                email = %s,
                phone = %s,
                num1 = %s,
                num2 = %s,
                num3 = %s,
                num4 = %s,
                num5 = %s,
                num6 = %s
            WHERE id = %s
        """, (fullname, email, phone, num1, num2, num3, num4, num5, num6, id))
        flash('Edision Exitosa')
        mysql.connection.commit()
        return redirect(url_for('Index'))

@app.route('/delete/<string:id>')
def delete_contact(id):
  cur = mysql.connection.cursor()
  cur.execute('DELETE from eval WHERE id = {0}'. format(id))
  mysql.connection.commit()
  flash('Contacto Eliminado')
  return redirect(url_for('Index'))

if __name__ == '__main__':
 app.run(port = 3000, debug = True)


# -*- coding: utf-8 -*-
"""
Define the APL class to represent and parse a simc profile.

@author: skasch
"""

from collections import OrderedDict

from .actions import ActionList, PrecombatAction
from ..objects.units import Player, Target, Unit
from ..objects.lua import LuaCastable
from .context import Context
from ..abstract.helpers import indent
from ..constants import IGNORED_ACTION_LISTS
from ..database import CLASS_SPECS, TEMPLATES

class APL:
    """
    The main class representing an Action Priority List (or simc profile),
    extracted from its simc string.
    """

    DEFAULT_TEMPLATE = ('{context}'
                        '\n--- ======= ACTION LISTS =======\n'
                        '-- [3] Single Rotation\n'
                        'A[3] = function(icon, isMulti)\n\n'
                        '    --------------------\n'
                        '    --- ROTATION VAR ---\n'
                        '    --------------------\n'
                        '    local isMoving = A.Player:IsMoving()\n'
                        '    local isMovingFor = A.Player:IsMovingTime()\n'
                        '    local inCombat = Unit(player):CombatTime() > 0\n'
	                    '    local combatTime = Unit(player):CombatTime()\n'
                        '    local ShouldStop = Action.ShouldStop()\n'
                        '    local Pull = Action.BossMods_Pulling()\n'
	                    '    local DBM = Action.GetToggle(1, "DBM")\n'
	                    '    local HeartOfAzeroth = Action.GetToggle(1, "HeartOfAzeroth")\n'
	                    '    local Racial = Action.GetToggle(1, "Racial")\n'
	                    '    local Potion = Action.GetToggle(1, "Potion")\n\n'
                        '    ------------------------------------------------------\n'
                        '    ---------------- ENEMY UNIT ROTATION -----------------\n'
                        '    ------------------------------------------------------\n'
                        '    local function EnemyRotation(unit)\n\n'
                        '{action_lists}\n'
                        '{precombat_call}\n\n'
                        '        -- In Combat\n'
                        '        if inCombat and Unit(unit):IsExists() then\n\n'
                        '        {main_actions}\n'
                        '        end\n'
                        '    end\n'
                        '\n{set_apl}')

    def __init__(self):
        self.simc_lines = []
        self.player = None
        self.target = Target()
        self.profile_name = ''
        self.parsed = True
        self.apl_simc = ''
        self.show_comments = True
        self.action_lists_simc = OrderedDict()
        self.context = Context()
        LuaCastable.cid = 0

    def hide_simc_comments(self):
        """
        Hide the default commented simc lines to the printed lua code.
        """
        self.show_comments = False

    def set_simc_lines(self, simc_lines):
        """
        Set the simc_lines attribute of the object to the content of the
        variable simc_lines.
        """
        self.simc_lines = [simc_line for simc_line in simc_lines
                           if not simc_line.startswith('#')]
        self.parsed = False

    def read_profile(self, file_path):
        """
        Read a .simc profile file.
        """
        with open(file_path, 'r') as profile:
            self.set_simc_lines([line.strip() for line in profile.readlines()])

    def read_string(self, multiline_simc):
        """
        Read a simc profile from a multiline string.
        """
        self.set_simc_lines(multiline_simc.split('\n'))

    def process_lua(self):
        """
        Parse the profile read from the simc_lines attribute and print the lua
        code generated by the profile.
        """
        self.parse_profile()
        return self.print_lua()

    def export_lua(self, file_path):
        """
        Parse the profile read from the simc_lines attribute and export the lua
        code generated into file_path.
        """
        self.parse_profile()
        with open(file_path, 'w') as lua_file:
            lua_file.write(self.print_lua())

    def parse_profile(self):
        """
        Parse the profile from the simc_lines attribute.
        """
        if not self.parsed:
            for simc in self.simc_lines:
                self.parse_line(simc)
            self.parsed = True

    def parse_action(self, simc):
        """
        Parse a single line from the simc_lines attribute if this line is an
        action and append it in its action_list in action_lists_simc dict.
        """
        equal_index = simc.find('+=')
        equal_len = 2
        if equal_index == -1:
            equal_index = simc.find('=')
            equal_len = 1
        if equal_index == -1:
            return
        action_call = simc[:equal_index]
        action_simc = simc[equal_index + equal_len:]
        if '.' not in action_call:
            self.apl_simc += action_simc
            return
        action_list_name = action_call.split('.')[1]
        if action_list_name not in IGNORED_ACTION_LISTS:
            if action_list_name in self.action_lists_simc:
                self.action_lists_simc[action_list_name] += action_simc
            else:
                self.action_lists_simc[action_list_name] = action_simc

    def precombat_action(self):
        """
        Get the call to precombat actions.
        """
        return PrecombatAction(self)

    def main_action_list(self):
        """
        Get the ActionList object for the main action list.
        """
        return ActionList(self, self.apl_simc, 'APL')

    def action_lists(self):
        """
        Get the list of ActionList objects from action_lists_simc.
        """
        return [ActionList(self, simc, name)
                for name, simc in self.action_lists_simc.items()]

    def parse_line(self, simc):
        """
        Parse a single line in simc_lines.
        """
        if any(simc.startswith(class_) for class_ in CLASS_SPECS):
            class_, profile_name = simc.split('=')
            self.set_player(class_)
            self.set_profile_name(profile_name)
        elif simc.startswith('spec'):
            _, spec = simc.split('=')
            self.player.set_spec(spec)
        elif simc.startswith('level'):
            _, level = simc.split('=')
            self.player.set_level(level)
        elif simc.startswith('race'):
            _, race = simc.split('=')
            self.player.set_race(race)
        elif simc.startswith('actions'):
            self.parse_action(simc)

    def set_profile_name(self, simc):
        """
        Set the profile name.
        """
        self.profile_name = simc.replace('"', '')

    def set_player(self, simc):
        """
        Set a player as the main actor of the APL.
        """
        self.player = Player(simc, self)
        self.context.set_player(self.player)

    def set_target(self, simc):
        """
        Set the target of the main actor of the APL.
        """
        self.target = Target(simc)

    def print_action_list_names(self):
        """
        Print the definition of action list names in local.
        """
        action_list_names_lua = [action_list.name.print_lua()
                                 for action_list in self.action_lists()]
        if len(action_list_names_lua) > 0:
            return indent('local ' + ', '.join(action_list_names_lua))
        return ''

    def print_action_lists_lua(self):
        """
        Print the lua string of the APL.
        """
        return '\n'.join(indent(action_list.print_lua())
                         for action_list in self.action_lists())

    def print_set_apl(self):
        """
        Print the call to SetAPL to set the APL into HR.
        """
        class_simc = self.player.class_.simc
        spec_simc = self.player.spec.simc
        apl_id = CLASS_SPECS.get(class_simc, {}).get(spec_simc, 0)
        return ('    -- End on EnemyRotation()\n\n'
        '    -- Defensive\n'
        '    --local SelfDefensive = SelfDefensives()\n'
        '    if SelfDefensive then \n'
        '        return SelfDefensive:Show(icon)\n'
        '    end \n\n'

        '    -- Mouseover\n'
        '    if A.IsUnitEnemy("mouseover") then\n'
        '        unit = "mouseover"\n'
        '        if EnemyRotation(unit) then \n'
        '            return true \n'
        '        end \n'
        '    end \n\n'

        '    -- Target  \n'
        '    if A.IsUnitEnemy("target") then \n'
        '        unit = "target"\n'

        '        if EnemyRotation(unit) then \n'
        '            return true\n'
        '        end \n\n'
        '    end\n'
        'end\n'
        '-- Finished\n\n'
        '-- [4] AoE Rotation\n'
        'A[4] = function(icon)\n'
        '    return A[3](icon, true)\n'
        'end\n '
        '-- [5] Trinket Rotation\n'
        '-- No specialization trinket actions \n'
        '-- Passive \n'
        '--[[local function FreezingTrapUsedByEnemy()\n'
        '    if     UnitCooldown:GetCooldown("arena", 3355) > UnitCooldown:GetMaxDuration("arena", 3355) - 2 and\n'
        '    UnitCooldown:IsSpellInFly("arena", 3355) and \n'
        '    Unit("player"):GetDR("incapacitate") >= 50 \n'
        '    then \n'
        '        local Caster = UnitCooldown:GetUnitID("arena", 3355)\n'
        '        if Caster and Unit(Caster):GetRange() <= 40 then \n'
        '            return true \n'
        '        end \n'
        '    end \n'
        'end \n'

        'local function ArenaRotation(icon, unit)\n'
        '    if A.IsInPvP and (A.Zone == "pvp" or A.Zone == "arena") and not Player:IsStealthed() and not Player:IsMounted() then\n'
        '        -- Note: "arena1" is just identification of meta 6\n'
        '        if (unit == "arena1" or unit == "arena2" or unit == "arena3") then \n'
        '            -- Reflect Casting BreakAble CC\n'
        '            if A.NetherWard:IsReady() and A.NetherWard:IsSpellLearned() and Action.ShouldReflect(EnemyTeam()) and EnemyTeam():IsCastingBreakAble(0.25) then \n'
        '                return A.NetherWard:Show(icon)\n'
        '            end \n'
        '        end\n'
        '    end \n'
        'end \n'

        'local function PartyRotation(unit)\n'
        '    if (unit == "party1" and not A.GetToggle(2, "PartyUnits")[1]) or (unit == "party2" and not A.GetToggle(2, "PartyUnits")[2]) then \n'
        '        return false \n'
        '    end\n\n'
        '  	-- SingeMagic\n'
        '    if A.SingeMagic:IsCastable() and A.SingeMagic:AbsentImun(unit, Temp.TotalAndMag) and IsSchoolFree() and Action.AuraIsValid(unit, "UseDispel", "Magic") and not Unit(unit):InLOS() then\n'
        '        return A.SingeMagic:Show(icon)\n'
        '    end\n'

        'end \n\n'
        'A[6] = function(icon)\n'
        '    return ArenaRotation(icon, "arena1")\n'
        'end\n\n'
        'A[7] = function(icon)\n'
        '    local Party = PartyRotation("party1") \n'
        '    if Party then \n'
        '        return Party:Show(icon)\n'
        '    end \n'

        '    return ArenaRotation(icon, "arena2")\n'
        'end\n\n'
        'A[8] = function(icon)\n'
        '    local Party = PartyRotation("party2") \n'
        '    if Party then \n'
        '        return Party:Show(icon)\n'
        '    end     \n'
        '    return ArenaRotation(icon, "arena3")\n'
        'end]]--\n\n'
                )

    def template(self):
        return TEMPLATES.get(self.player.class_.simc+self.player.spec.simc, self.DEFAULT_TEMPLATE)

    def print_lua(self):
        """
        Print the lua string representing the action list.
        """
        function_name = self.main_action_list().name.lua_name()
        action_list_names = self.print_action_list_names()
        action_lists = self.print_action_lists_lua()
        precombat_call = self.precombat_action().print_lua()
        main_actions = self.main_action_list().print_actions_lua()
        context = self.context.print_lua()
        set_apl = self.print_set_apl()
        return self.template().format(
            context=context,
            function_name=function_name,
            action_list_names=indent(action_list_names),
            action_lists=indent(action_lists),
            precombat_call=precombat_call,
            main_actions=indent(indent(main_actions)),
            set_apl=set_apl
        )


from hisclay.settings_base import *

DEBUG = True

TEMPLATE_DEBUG = DEBUG

ALLOWED_HOSTS = ['127.0.0.1']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.hisclay'),
    }
}

STATIC_URL = '/static/'


fh = open('t.txt','r')
lst = list()
for line in fh:
    l=line.split()
    for w in l:
        if not w in lst:
            continue
        lst=lst.append(w)
lst.sort()
print(lst)


import logging
import hashlib
import json
import requests
from .http_util import get_cookie_from_cookiejar

lg = logging.getLogger('xiami.client')

class HTTPClient:
    base_uri = None

    def __init__(self, session: requests.Session, base_uri=None, headers=None):
        if base_uri:
            self.base_uri = base_uri
        self.headers = headers or {}
        self.session = session

    def request(self, method, uri, *args, **kwargs):
        url = self.base_uri + uri
        if 'headers' in kwargs:
            headers = dict(self.headers)
            headers.update(kwargs['headers'])
            kwargs['headers'] = headers
        else:
            if self.headers:
                kwargs['headers'] = self.headers

        if 'json_data' in kwargs:
            kwargs['data'] = json.dumps(kwargs.pop('json_data'))
            if 'headers' in kwargs:
                kwargs['headers'].update({
                    'Content-Type': 'application/json',
                })
        lg.debug(
            'HTTPClient request, %s, %s, %s, %s',
            method, url, args, kwargs)
        resp = getattr(self.session, method)(url, *args, **kwargs)
        lg.debug('Response: %s, %s', resp.status_code, resp.content[:100])
        return resp

    def get(self, uri, *args, **kwargs):
        return self.request('get', uri, *args, **kwargs)

    def post(self, uri, *args, **kwargs):
        return self.request('post', uri, *args, **kwargs)

class XiamiClient(HTTPClient):
    base_uri = 'https://www.xiami.com'

    def __init__(self, session, headers=None):
        super().__init__(session, headers=headers)

    # API methods

    def set_user_id(self, user_id):
        self.user_id = user_id

    def make_page_q(self, page, page_size):
        q = {
            "userId": self.user_id,
            "type": 1,
            "pagingVO": {
                "page": page,
                "pageSize": page_size,
            },
        }
        return q

    def get_fav_songs(self, page, page_size=30):
        lg.info(f'get_fav_songs: page={page}')
        uri = '/api/favorite/getFavorites'
        q = self.make_page_q(page, page_size)
        params = {
            '_q': param_json_dump(q),
            '_s': create_token(self.session, uri, q),
        }
        r = self.get(uri, params=params)
        # print(r.status_code, r.content.decode('utf-8'))
        data = r.json()

        # when out of max page, songs is "null"
        return data['result']['data']['songs']

    def get_play_info(self, song_ids):
        lg.info(f'get_play_info: song_ids={song_ids}')
        uri = '/api/song/getPlayInfo'
        q = {
            'songIds': song_ids,
        }
        r = self.get(uri, params={
            '_q': param_json_dump(q),
            '_s': create_token(self.session, uri, q),
        })
        data = r.json()

        return data['result']['data']['songPlayInfos']

def param_json_dump(o):
    return json.dumps(o, separators=(',', ':'))

def create_token(session, path, q):
    tk = get_cookie_from_cookiejar(session.cookies, 'xm_sg_tk')
    if not tk:
        raise ValueError('could not get xm_sg_tk from cookie')
    if q:
        q_json = param_json_dump(q)
    else:
        q_json = ''
    token_value = tk.value.split('_')[0] + '_xmMain_' + path + '_' + q_json
    token = get_md5_hex(token_value.encode())
    return token

def get_md5_hex(b: bytes):
    return hashlib.md5(b).hexdigest()


import RPi.GPIO as GPIO
import time
def callback(channel):
    global led_state
    led_state=not led_state
    print("led_state:",led_state)
    if led_state==GPIO.HIGH:
        GPIO.output(25,GPIO.HIGH)    # Lights LED.
    else:
        GPIO.output(25,GPIO.LOW)
GPIO.setmode(GPIO.BCM)   # Uses GPIO pin numbers.
GPIO.setup(24,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(25,GPIO.OUT,initial=GPIO.LOW)
GPIO.add_event_detect(24,GPIO.RISING,callback=callback,bouncetime=200)
led_state=GPIO.LOW
try:
    while True:
        time.sleep(0.01)  # idle.
except KeyboardInterrupt:
    pass  # Terminates program with Ctrl+C.
GPIO.cleanup()  # Initializes GPIO.setup().


import multiprocessing as mp

from szqj.authors_networking.account_networking import *
from utils.mysql import data_fetch, Database, row_count

def update_author_networking_from_meta():
    start = 0
    db = Database()
    total = int(data_fetch("COUNT(*)", "essays", start=start, limit=None)[0][0])
    scan_count = start
    insert_count = 0
    limit = 10000

    while scan_count < total:

        if limit > total - scan_count:
            limit = total - scan_count

        data = data_fetch("*", "essays", start=start, limit=limit)

        for raw_item in data:
            obj = Essay(raw_item)
            response = obj.author_insert(db.conn)
            scan_count += 1
            if response:
                insert_count += response

            if scan_count % 1000 == 0:
                print(
                    "Scanned {} out of {} essays \n Inserted {} relation \n \n".format(scan_count, total, insert_count))
        start += limit

def worker(w_id, start, end):
    print("===============Process {} has started================".format(w_id))

    db = Database()
    total = end
    scan_count = 0
    limit = 10000
    chunk_size = end - start

    media_inserted = 0
    author_inserted = 0

    while scan_count < (end - start):

        if limit > total - scan_count - start:
            limit = total - scan_count - start

        data = data_fetch("*", "essays", start=start, limit=limit, tail_condition="ORDER BY `insert_time` DESC")

        for raw_item in data:
            obj = Essay(raw_item)
            media_count, author_count = obj.extractor_info_insert(db.conn)
            author_count += obj.meta_author_insert(db.conn)
            scan_count += 1
            if media_count + author_count:
                media_inserted += media_count
                author_inserted += author_count

            if scan_count % 1000 == 0:
                print(
                    "Process {} has scanned {} out of {} essays \n Inserted {} author relations \n Inserted {} media relations\n".format(
                        w_id, scan_count, chunk_size, author_inserted, media_inserted))
        start += limit
    print("===============Process {} has ended================".format(w_id))

if __name__ == "__main__":
    _ = 1

    num = row_count("essays", host_IP="192.168.164.15", database="raw")

    manager = mp.Manager()
    items = manager.list()

    process_num = 2
    inputs = []
    start_ind = 0
    chunk = int((num - start_ind) / process_num)

    for i in range(process_num):
        inputs.append((start_ind, start_ind + chunk))
        start_ind += chunk + 1
    print(inputs)
    counter = 0
    processes = []
    for input1, input2 in inputs:
        processes.append(mp.Process(target=worker, args=(counter, input1, input2,)))
        counter += 1

    # 运行所有进程
    for p in processes:
        p.start()

    # 确定所有进程结束
    for p in processes:
        p.join()


import logging
from allennlp.common.util import import_submodules
from allennlp.common.checks import check_for_gpu
from allennlp.models.archival import load_archive
from allennlp.predictors.predictor import Predictor
from allennlp.common import Params
from allennlp.commands.train import train_model
from allennlp.commands.fine_tune import fine_tune_model
from allennlp.commands.evaluate import evaluate
from allennlp.common.util import prepare_environment
from allennlp.data.dataset_readers.dataset_reader import DatasetReader
from allennlp.data.iterators import DataIterator
import sys

logger = logging.getLogger(__name__)

"""
预测
"""
def predict(**params):
    param_is_exist(["include_package", "model_file", "input"], params)
    for package_name in params["include_package"]:
        import_submodules(package_name)
    cuda = params["cuda"] if "cuda" in params else -1
    overrides = params["overrides"] if "overrides" in params else ""
    check_for_gpu(cuda)
    archive = load_archive(params["model_file"], cuda_device=cuda, overrides=overrides)
    predictor = Predictor.from_archive(archive, params["predictor"])
    # try:
    #     archive = load_archive(params["model_file"], cuda_device=cuda, overrides=overrides)
    #     predictor = Predictor.from_archive(archive, params["predictor"])
    # except Exception:
    #     print("请先下载预训练模型或者自己训练模型放在pretrain_model目录下面")
    #     sys.exit()
    results = predictor.predict_json(params["input"])
    return results

"""
训练
"""
def train(**params):
    param_is_exist(["config_file", "serialization_dir", "include_package"], params)
    for package_name in params["include_package"]:
        import_submodules(package_name)
    overrides = params["overrides"] if "overrides" in params else ""
    recover = params["recover"] if "recover" in params else False
    force = params["force"] if "force" in params else False
    config_params = Params.from_file(params["config_file"], overrides)
    return train_model(config_params, params["serialization_dir"], recover=recover, force=force,file_friendly_logging=True)

"""
微调模型
"""
def fine_tune(**params):
    param_is_exist(["config_file", "serialization_dir", "include_package", "model_file"], params)
    for package_name in params["include_package"]:
        import_submodules(package_name)
    overrides = params["overrides"] if "overrides" in params else ""
    recover = params["recover"] if "recover" in params else ""
    force = params["force"] if "force" in params else ""
    config_params = Params.from_file(params["config_file"], overrides)
    archive = load_archive(params["model_file"])
    return fine_tune_model(archive.model, config_params, params["serialization_dir"], recover, force)

"""
评测模型
"""
def evaluating(**params):
    param_is_exist(["model_file", "input_file", "include_package"], params)
    for package_name in params["include_package"]:
        import_submodules(package_name)
    cuda_device = params["cuda_device"] if "cuda_device" in params else -1
    overrides = params["overrides"] if "overrides" in params else ""
    weights_file = params["weights_file"] if "weights_file" in params else ""
    archive = load_archive(params["model_file"], cuda_device, overrides, weights_file)
    config = archive.config
    prepare_environment(config)
    model = archive.model
    model.eval()

    # Load the evaluation data

    # Try to use the validation dataset reader if there is one - otherwise fall back
    # to the default dataset_reader used for both training and validation.
    validation_dataset_reader_params = config.pop('validation_dataset_reader', None)
    if validation_dataset_reader_params is not None:
        dataset_reader = DatasetReader.from_params(validation_dataset_reader_params)
    else:
        dataset_reader = DatasetReader.from_params(config.pop('dataset_reader'))
    evaluation_data_path = params["input_file"]
    logger.info("Reading evaluation data from %s", evaluation_data_path)
    instances = dataset_reader.read(evaluation_data_path)

    iterator_params = config.pop("validation_iterator", None)
    if iterator_params is None:
        iterator_params = config.pop("iterator")
    iterator = DataIterator.from_params(iterator_params)
    iterator.index_with(model.vocab)
    metrics = evaluate(model, instances, iterator, cuda_device)
    logger.info("Finished evaluating.")
    logger.info("Metrics:")
    for key, metric in metrics.items():
        logger.info("%s: %s", key, metric)

    return metrics

def cover_dict(a: dict, b: dict):
    return dict(a, **b)

def param_is_exist(required_param:list, param_list=dict):
    """
    需要的参数是否在字典里面
    """
    error_param = [r_param for r_param in required_param if r_param not in param_list]
    if len(error_param) > 0:
        error_param = ",".join(error_param)
        print("缺少如下参数"+error_param)
        sys.exit()

def format_sentence(sentence:str):
    return " ".join(sentence.strip().replace(" ", ""))

def format_ner_result(results:dict):
    res = []
    entity = ""
    words = results["words"]
    tags = results["tags"]
    for index, tag in enumerate(tags):  # for every word
        if tag[0] == 'B':
            entity += words[index]
        elif tag[0] == 'M':
            entity += words[index]
        elif tag[0] == 'E':
            entity += words[index]
            res.append(entity)
            st = ""
            for s in entity:
                st += s + ' '
            entity = ""
        elif tag[0] == 'S':
            entity = words[index]
            res.append(entity)
            entity = ""
        else:
            entity = ""
    return " ".join(res)

def format_postag_result(results:dict):
    words = results["words"]
    tags = results["tags"]
    res = [str(words[index])+"/"+str(tag) for index, tag in enumerate(tags)]
    return " ".join(res)

def format_classify_result(results:dict):
    return results["label"]

def bmes_to_words(results:dict,require_s=True):
    chars = results["words"]
    tags = results["tags"]
    result = []
    if len(chars) == 0:
        return result
    word = chars[0]

    for c, t in zip(chars[1:], tags[1:]):
        if t[0] == 'B' or t[0] == 'S':
            result.append(word)
            word = ''
        word += c
    if len(word) != 0:
        result.append(word)
    return " ".join(result)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import messages
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render, get_object_or_404, get_list_or_404, redirect
from django.http import HttpResponse, HttpResponseRedirect

from .forms import PostForm
from .models import Post

# Create your views here.
def post_create(request):
	form = PostForm(request.POST or None)
	if form.is_valid():
		instance = form.save(commit=False)
		#print form.cleaned_data.get('titulo')
		instance.save()
		messages.success(request, 'Tu post se ha creado con éxito')
		return HttpResponseRedirect(instance.get_absolute_url())
	#if request.method == 'POST':
	#	print request.POST
	context = {
		'form':form,
	}
	return render(request, 'post_form.html', context)
	#return HttpResponse("
CREATE
")

def post_detail(request, id=None):
	instance = get_object_or_404(Post, id=id)
	context = {
		'titulo': 'detail',
		'instance': instance
	}
	return render(request, 'post_detail.html', context)

def post_list(request):
	#queryset = get_list_or_404(Post).order_by("-timestamp")
	queryset = get_list_or_404(Post)

	paginator = Paginator(queryset, 5)

	page = request.GET.get('page')
	try:
		posts = paginator.page(page)
	except PageNotAnInteger:
		posts = paginator.page(1)
	except EmptyPage:
		posts = paginator.page(paginator.num_pages)

	context = {
		'titulo': 'list',
		'data': posts,
	}

	return render(request, 'post_list.html', context)

def post_update(request, id=None):
	instance = get_object_or_404(Post, id=id)
	form = PostForm(request.POST or None, instance=instance)
	if form.is_valid():
		instance = form.save(commit=False)
		#print form.cleaned_data.get('titulo')
		instance.save()
		messages.success(request, 'Tu post se ha actualizado con éxito', extra_tags="otra-clase")
		return HttpResponseRedirect(instance.get_absolute_url())
	context = {
		'titulo': instance.titulo,
		'instance': instance,
		'form':form,
	}
	return render(request, 'post_form.html', context)
	#return HttpResponse("
UPDATE
")

def post_delete(request, id):
	instance = get_object_or_404(Post, id=id)
	instance.delete()
	messages.success(request, 'Tu post se ha eliminado con éxito', extra_tags="otra-clase")
	return redirect('posts:list')


from enum import Enum
import math
import MLKit

class ColumnAttributes:

    class Type(Enum):

        string = 0
        numeric = 1

        @staticmethod
        def type_of_value(value):
            try:
                float(value)
                return ColumnAttributes.Type.numeric
            except ValueError:
                pass

            return ColumnAttributes.Type.string

        @staticmethod
        def name_of_type(column_type):
            if column_type == ColumnAttributes.Type.string:
                return "String"
            elif column_type == ColumnAttributes.Type.numeric:
                return "Numeric"
            return None

    def __init__(self, column):
        self.count = 0
        self.mean = None
        self.minimum = float("inf")
        self.maximum = -float("inf")
        self.percent_25 = None
        self.percent_50 = None
        self.percent_75 = None
        self.std = None
        self.type = None
        self.numeric_values = {}
        self.__compute_attributes(column)

    def __compute_attributes(self, column):
        values_sum = 0

        for value in column.values:
            if value == None:
                continue

            if not self.__is_type_correct_for_value(value):
                MLKit.Display.warning("Column " + column.name + " contains different value types.")
                self.minimum = None
                self.maximum = None
                return

            self.__transform_value_to_numeric_if_needed(value)

            float_value = self.numeric_value_for_value(value)
            values_sum += float_value
            self.count += 1

            if float_value < self.minimum:
                self.minimum = float_value
            if float_value > self.maximum:
                self.maximum = float_value

        if self.count == 0:
            return

        self.mean = values_sum / self.count
        self.percent_25 = 0
        self.percent_50 = 0
        self.percent_75 = 0
        squared_sum = 0

        replaced_values = []
        for value in column.values:
            if value is None:
                continue
            replaced_values.append(self.numeric_value_for_value(value))
        sorted_values = sorted(replaced_values)

        for (index, value) in enumerate(sorted_values):
            if value == None:
                continue

            squared_sum += (self.mean - value) ** 2

            if index == round(self.count / 4):
                self.percent_25 = value
            if index == round(self.count / 2):
                self.percent_50 = value
            if index == round(3 * self.count / 4):
                self.percent_75 = value

        variance = squared_sum / self.count
        self.std = math.sqrt(variance)

    def __is_type_correct_for_value(self, value):
        if value == None:
            return True

        if self.type == ColumnAttributes.Type.string and value == "Nan":
            return True
        elif self.type == None:
            self.type = ColumnAttributes.Type.type_of_value(value)
            return True
        elif self.type == ColumnAttributes.Type.type_of_value(value):
            return True
        else:
            return False

    def __transform_value_to_numeric_if_needed(self, value):
        if value == None or self.type == ColumnAttributes.Type.numeric:
            return

        if self.numeric_values.get(value) == None:
            self.numeric_values[value] = len(self.numeric_values.keys())

    def numeric_value_for_value(self, value):
        if self.type == ColumnAttributes.Type.numeric:
            return float(value)

        return self.numeric_values[value]

    def value_for_key(self, name):
        if name == "Type":
            return ColumnAttributes.Type.name_of_type(self.type)
        elif name == "Count":
            return self.count
        elif name == "Mean":
            return self.mean
        elif name == "Std":
            return self.std
        elif name == "Min":
            return self.minimum
        elif name == "25%":
            return self.percent_25
        elif name == "50%":
            return self.percent_50
        elif name == "75%":
            return self.percent_75
        elif name == "Max":
            return self.maximum
        else:
            return None

    @staticmethod
    def all():
        return ["Type", "Count", "Mean", "Std", "Min", "25%", "50%", "75%", "Max"]


import sys
from client_simulation import *
from message import *
import enum
import sip
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt

# Use the more modern PyQt API (not enabled by default in Python 2.x);
# must precede importing any module that provides the API specified
sip.setapi('QDate', 2)
sip.setapi('QDateTime', 2)
sip.setapi('QString', 2)
sip.setapi('QTextStream', 2)
sip.setapi('QTime', 2)
sip.setapi('QUrl', 2)
sip.setapi('QVariant', 2)

# Default motor speeds {DRIVE_MOTORS, ACTUATOR, BUCKET}
MOTOR_SPEEDS = {0: 100, 1: 100, 2: 100}

MAX_MOTOR_SPEED = 100
BUFFER = []

class Motor(enum.Enum):
    DRIVE_MOTORS = 0
    ACTUATOR = 1
    BUCKET = 2

class Window(QWidget):
    def __init__(self, client):
        super(Window, self).__init__()

        self.client = client

        self.drive_keys_pressed = []

        self.actuator_keys_pressed = []

        self.bucket_keys_pressed = []

        self.motor_speed_to_adjust = Motor.DRIVE_MOTORS.value

        self.init_ui()

    def init_ui(self):
        # Button to open the connection
        self.open_connection_button = QtWidgets.QPushButton('Open Connection', self)
        self.open_connection_button.clicked.connect(self.open_connection_event)
        self.open_connection_button.setFocusPolicy(QtCore.Qt.NoFocus)

        # Button to close the connection
        self.close_connection_button = QtWidgets.QPushButton('Close Connection', self)
        self.close_connection_button.clicked.connect(self.close_connection_event)
        self.close_connection_button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.close_connection_button.setEnabled(False)

        # Button to activate autonomy
        self.activate_autonomy_button = QtWidgets.QPushButton('Activate Autonomy', self)
        self.activate_autonomy_button.clicked.connect(self.activate_autonomy_event)
        self.activate_autonomy_button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.activate_autonomy_button.setEnabled(False)

        # Button to deactivate autonomy
        self.deactivate_autonomy_button = QtWidgets.QPushButton('Deactivate Autonomy', self)
        self.deactivate_autonomy_button.clicked.connect(self.deactivate_autonomy_event)
        self.deactivate_autonomy_button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.deactivate_autonomy_button.setEnabled(False)

        # Button to run simulation
        self.simulation_button = QtWidgets.QPushButton('Simulation', self)
        self.simulation_button.move(0, 30)
        self.simulation_button.clicked.connect(self.simulation_event)
        self.simulation_button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.simulation_button.setEnabled(True)

        # Button to run real time tracking
        self.real_time_tracking_button = QtWidgets.QPushButton('Real Time Tracking', self)
        self.real_time_tracking_button.clicked.connect(self.real_time_tracking_event)
        self.real_time_tracking_button.setFocusPolicy(QtCore.Qt.NoFocus)
        self.real_time_tracking_button.setEnabled(False)

        grid =  QtWidgets.QGridLayout()
        grid.setSpacing(10)

        h_box_0 = QtWidgets.QHBoxLayout()
        h_box_0.addStretch(1)
        h_box_0.addWidget(self.open_connection_button)
        h_box_0.addWidget(self.close_connection_button)

        h_box_1 = QtWidgets.QHBoxLayout()
        h_box_1.addStretch(1)
        h_box_1.addWidget(self.activate_autonomy_button)
        h_box_1.addWidget(self.deactivate_autonomy_button)

        v_box = QtWidgets.QVBoxLayout()
        v_box.addStretch(1)
        v_box.addLayout(grid)
        v_box.addLayout(h_box_0)
        v_box.addLayout(h_box_1)

        self.setLayout(v_box)

        self.resize(500, 400)
        self.center()

        self.setWindowTitle('Client')
        self.setWindowIcon(QtGui.QIcon('mars.png'))

        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QtWidgets.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def keyPressEvent(self, event):
        if self.open_connection_button.isEnabled() \
                or self.deactivate_autonomy_button.isEnabled():
            return

        key = event.key()

        if not event.isAutoRepeat():
            # Driving logic
            if key == QtCore.Qt.Key_W:
                #BUFFER.append('W\n')
                if key not in self.drive_keys_pressed:
                    self.drive_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value],
                                'r': MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_S:
                #BUFFER.append('S\n')
                if key not in self.drive_keys_pressed:
                    self.drive_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': -1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value],
                                'r': -1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_A:
                #BUFFER.append('A\n')
                if key not in self.drive_keys_pressed:
                    self.drive_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': -1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value],
                                'r': 1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_D:
                #BUFFER.append('D\n')
                if key not in self.drive_keys_pressed:
                    self.drive_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': 1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value],
                                'r': -1 * MOTOR_SPEEDS[Motor.DRIVE_MOTORS.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

            # Motor speed adjustment mode logic
            elif key == QtCore.Qt.Key_1:
                #BUFFER.append('1\n')
                self.motor_speed_to_adjust = Motor.DRIVE_MOTORS.value
                print ('Motor speed adjustment mode:'), str(self.motor_speed_to_adjust)
            elif key == QtCore.Qt.Key_2:
                #BUFFER.append('2\n')
                self.motor_speed_to_adjust = Motor.ACTUATOR.value
                print ('Motor speed adjustment mode:'), str(self.motor_speed_to_adjust)
            elif key == QtCore.Qt.Key_3:
                #BUFFER.append('3\n')
                self.motor_speed_to_adjust = Motor.BUCKET.value
                print ('Motor speed adjustment mode:'), str(self.motor_speed_to_adjust)

            # Actuator logic
            elif key == QtCore.Qt.Key_U:
                #BUFFER.append('U\n')
                if key not in self.actuator_keys_pressed:
                    self.actuator_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'a': MOTOR_SPEEDS[Motor.ACTUATOR.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_J:
                #BUFFER.append('J\n')
                if key not in self.actuator_keys_pressed:
                    self.actuator_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'a': -1 * MOTOR_SPEEDS[Motor.ACTUATOR.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

            # Bucket logic
            elif key == QtCore.Qt.Key_I:
                #BUFFER.append('I\n')
                if key not in self.bucket_keys_pressed:
                    self.bucket_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'b': MOTOR_SPEEDS[Motor.BUCKET.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_K:
                #BUFFER.append('K\n')
                if key not in self.bucket_keys_pressed:
                    self.bucket_keys_pressed.append(key)

                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'b': -1 * MOTOR_SPEEDS[Motor.BUCKET.value]}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

        # Motor speed adjustment logic
        if key == QtCore.Qt.Key_Up:
            #BUFFER.append('Up\n')
            if MOTOR_SPEEDS[self.motor_speed_to_adjust] < MAX_MOTOR_SPEED:
                MOTOR_SPEEDS[self.motor_speed_to_adjust] += 1
                print (MOTOR_SPEEDS[self.motor_speed_to_adjust])
                if len(self.drive_keys_pressed):
                    self.keyPressEvent(Qt.QKeyEvent(Qt.QEvent.KeyPress, self.drive_keys_pressed[-1],
                                                    QtCore.Qt.NoModifier))
        elif key == QtCore.Qt.Key_Down:
            #BUFFER.append('Down\n')
            if MOTOR_SPEEDS[self.motor_speed_to_adjust] > 0:
                MOTOR_SPEEDS[self.motor_speed_to_adjust] -= 1
                print (MOTOR_SPEEDS[self.motor_speed_to_adjust])
                if len(self.drive_keys_pressed):
                    self.keyPressEvent(Qt.QKeyEvent(Qt.QEvent.KeyPress, self.drive_keys_pressed[-1],
                                                    QtCore.Qt.NoModifier))
    def keyReleaseEvent(self, event):
        if event.isAutoRepeat() or self.open_connection_button.isEnabled() \
                or self.deactivate_autonomy_button.isEnabled():
            return

        key = event.key()

        if key in self.drive_keys_pressed:
            self.drive_keys_pressed.remove(key)

        if key in self.actuator_keys_pressed:
            self.actuator_keys_pressed.remove(key)

        if key in self.bucket_keys_pressed:
            self.bucket_keys_pressed.remove(key)

        # Driving logic
        if not len(self.drive_keys_pressed):
            if key == QtCore.Qt.Key_W:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': 0, 'r': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_S:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': 0, 'r': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_A:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': 0, 'r': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_D:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'l': 0, 'r': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

        # Actuator logic
        if not len(self.actuator_keys_pressed):
            if key == QtCore.Qt.Key_U:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'a': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_J:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'a': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

        # Bucket logic
        if not len(self.bucket_keys_pressed):
            if key == QtCore.Qt.Key_I:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'b': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)
            elif key == QtCore.Qt.Key_K:
                forwarding_prefix = ForwardingPrefix.MOTOR.value
                sub_messages = {'b': 0}
                message = Message(forwarding_prefix, sub_messages).message
                self.client.send_message(message)

    def open_connection_event(self):
        self.client.open_connection()
        self.open_connection_button.setEnabled(False)
        self.close_connection_button.setEnabled(True)
        self.real_time_tracking_button.setEnabled(True)
        self.simulation_button.setEnabled(False)
        self.activate_autonomy_button.setEnabled(True)

    def close_connection_event(self):
        if self.deactivate_autonomy_button.isEnabled():
            autonomy_message = 'Please deactivate autonomy first.'
            QtWidgets.QMessageBox.question(self, 'Message',
                                           autonomy_message, QtWidgets.QMessageBox.Ok)
            return

        quit_message = 'Are you sure you want to close the connection?'
        reply = QtWidgets.QMessageBox.question(self, 'Message',
                                               quit_message,
                                               QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.Yes)

        if reply == QtWidgets.QMessageBox.Yes:
            self.client.close_connection()

            self.open_connection_button.setEnabled(True)
            self.close_connection_button.setEnabled(False)

            self.activate_autonomy_button.setEnabled(False)
            self.deactivate_autonomy_button.setEnabled(False)

    def activate_autonomy_event(self):
        quit_message = 'Are you sure you want to activate autonomy?'
        reply = QtWidgets.QMessageBox.question(self, 'Message',
                                               quit_message,
                                               QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.Yes)

        if reply == QtWidgets.QMessageBox.Yes:
            self.activate_autonomy()

    def activate_autonomy(self):
        self.client.send_message(ForwardingPrefix.CONTROLLER.value + AUTONOMY_ACTIVATION_MESSAGE)

        self.activate_autonomy_button.setEnabled(False)
        self.deactivate_autonomy_button.setEnabled(True)

    def deactivate_autonomy_event(self):
        deactivateMessage = 'Are you sure you want to deactivate autonomy?'
        reply = QtWidgets.QMessageBox.question(self, 'Message',
                                               deactivateMessage,
                                               QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.Yes)

        if reply == QtWidgets.QMessageBox.Yes:
            self.deactivate_autonomy()

    def deactivate_autonomy(self):
        self.client.send_message(ForwardingPrefix.CONTROLLER.value + AUTONOMY_DEACTIVATION_MESSAGE)

        self.activate_autonomy_button.setEnabled(True)
        self.deactivate_autonomy_button.setEnabled(False)

    def simulation_event(self):
        sim = Setup()
        sim.start()

    def real_time_tracking_event(self):
        print()

    def closeEvent(self, QCloseEvent):
        quit_message = 'Are you sure you want to exit the client?'
        reply = QtWidgets.QMessageBox.question(self, 'Message',
                                               quit_message,
                                               QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.Yes)

        if reply == QtWidgets.QMessageBox.Yes:
            if self.deactivate_autonomy_button.isEnabled():
                self.deactivate_autonomy()
            self.client.shutdown()
            QCloseEvent.accept()
        else:
            QCloseEvent.ignore()

def main(client):
    app = QApplication(sys.argv)
    window = Window(client)
    # log = open('key_press_log.txt', 'w')
    # log.write('Key Press Log: \n')
    # for i in BUFFER:
    #     log.write(i)
    # log.close()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()