<commit_before>#pylint: disable=no-self-use
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------
"""
This module is the requests implementation of Pipeline ABC
"""
from __future__ import absolute_import  # we have a "requests" module that conflicts with "requests" on Py2.7
import logging
import time
import email
from typing import TYPE_CHECKING, List, Callable, Iterator, Any, Union, Dict, Optional  # pylint: disable=unused-import

from azure.core.exceptions import (
    AzureError,
    ServiceResponseError,
    ServiceRequestError
)

from .base import HTTPPolicy, RequestHistory

_LOGGER = logging.getLogger(__name__)

class RetryPolicy(HTTPPolicy):
    """A retry policy.

    The retry policy in the pipeline can be configured directly, or tweaked on a per-call basis.

    Keyword arguments:
    :param int retry_total: Total number of retries to allow. Takes precedence over other counts.
     Default value is 10.
    :param int retry_connect: How many connection-related errors to retry on.
     These are errors raised before the request is sent to the remote server,
     which we assume has not triggered the server to process the request. Default value is 3.
    :param int retry_read: How many times to retry on read errors.
     These errors are raised after the request was sent to the server, so the
     request may have side-effects. Default value is 3.
    :param int retry_status: How many times to retry on bad status codes. Default value is 3.
    :param int retry_backoff_factor: A backoff factor to apply between attempts after the second try
     (most errors are resolved immediately by a second try without a delay).
     Retry policy will sleep for: `{backoff factor} * (2 ** ({number of total retries} - 1))`
     seconds. If the backoff_factor is 0.1, then the retry will sleep
     for [0.0s, 0.2s, 0.4s, ...] between retries. The default value is 0.8.
    :param int retry_backoff_max: The maximum back off time. Default value is 120 seconds (2 minutes).

    Example:
        .. literalinclude:: ../../../../examples/examples_sync.py
            :start-after: [START retry_policy]
            :end-before: [END retry_policy]
            :language: python
            :dedent: 4
            :caption: Configuring a retry policy.
    """

    #: Maximum backoff time.
    BACKOFF_MAX = 120

    def __init__(self, **kwargs):
        self.total_retries = kwargs.pop('retry_total', 10)
        self.connect_retries = kwargs.pop('retry_connect', 3)
        self.read_retries = kwargs.pop('retry_read', 3)
        self.status_retries = kwargs.pop('retry_status', 3)
        self.backoff_factor = kwargs.pop('retry_backoff_factor', 0.8)
        self.backoff_max = kwargs.pop('retry_backoff_max', self.BACKOFF_MAX)

        safe_codes = [i for i in range(500) if i != 408] + [501, 505]
        retry_codes = [i for i in range(999) if i not in safe_codes]
        status_codes = kwargs.pop('retry_on_status_codes', [])
        self._retry_on_status_codes = set(status_codes + retry_codes)
        self._method_whitelist = frozenset(['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'])
        self._respect_retry_after_header = True
        super(RetryPolicy, self).__init__()

    @classmethod
    def no_retries(cls):
        """Disable retries.
        """
        return cls(retry_count_total=0)

    def configure_retries(self, options):
        """Configures the retry settings.

        :param options: keyword arguments from context.
        :return: A dict containing settings and history for retries.
        :rtype: dict
        """
        return {
            'total': options.pop("retry_total", self.total_retries),
            'connect': options.pop("retry_connect", self.connect_retries),
            'read': options.pop("retry_read", self.read_retries),
            'status': options.pop("retry_status", self.status_retries),
            'backoff': options.pop("retry_backoff_factor", self.backoff_factor),
            'max_backoff': options.pop("retry_backoff_max", self.BACKOFF_MAX),
            'methods': options.pop("retry_on_methods", self._method_whitelist),
            'history': []
        }

    def get_backoff_time(self, settings):
        """Returns the current backoff time.

        :param dict settings: The retry settings.
        :return: The current backoff value.
        :rtype: float
        """
        # We want to consider only the last consecutive errors sequence (Ignore redirects).
        consecutive_errors_len = len(settings['history'])
        if consecutive_errors_len <= 1:
            return 0

        backoff_value = settings['backoff'] * (2 ** (consecutive_errors_len - 1))
        return min(settings['max_backoff'], backoff_value)

    def parse_retry_after(self, retry_after):
        """Helper to parse Retry-After and get value in seconds.

        :param str retry_after: Retry-After header
        :rtype: int
        """
        try:
            seconds = int(retry_after)
        except TypeError:
            retry_date_tuple = email.utils.parsedate(retry_after)
            if retry_date_tuple is None:
                return None
            retry_date = time.mktime(retry_date_tuple)
            seconds = retry_date - time.time()

        if seconds < 0:
            seconds = 0
        return seconds

    def get_retry_after(self, response):
        """Get the value of Retry-After in seconds.

        :param response: The PipelineResponse object
        :type response: ~azure.core.pipeline.PipelineResponse
        :return: Value of Retry-After in seconds.
        :rtype: int
        """
        retry_after = response.http_response.headers.get("Retry-After")
        if retry_after is None:
            return None
        return self.parse_retry_after(retry_after)

    def _sleep_for_retry(self, response, transport):
        """Sleep based on the Retry-After response header value.

        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :param transport: The HTTP transport type.
        """
        retry_after = self.get_retry_after(response)
        if retry_after:
            transport.sleep(retry_after)
            return True
        return False

    def _sleep_backoff(self, settings, transport):
        """Sleep using exponential backoff. Immediately returns if backoff is 0.

        :param dict settings: The retry settings.
        :param transport: The HTTP transport type.
        """
        backoff = self.get_backoff_time(settings)
        if backoff <= 0:
            return
        transport.sleep(backoff)

    def sleep(self, settings, transport, response=None):
        """Sleep between retry attempts.

        This method will respect a server's ``Retry-After`` response header
        and sleep the duration of the time requested. If that is not present, it
        will use an exponential backoff. By default, the backoff factor is 0 and
        this method will return immediately.

        :param dict settings: The retry settings.
        :param transport: The HTTP transport type.
        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        """
        if response:
            slept = self._sleep_for_retry(response, transport)
            if slept:
                return
        self._sleep_backoff(settings, transport)

    def _is_connection_error(self, err):
        """Errors when we're fairly sure that the server did not receive the
        request, so it should be safe to retry.
        """
        return isinstance(err, ServiceRequestError)

    def _is_read_error(self, err):
        """Errors that occur after the request has been started, so we should
        assume that the server began processing it.
        """
        return isinstance(err, ServiceResponseError)

    def _is_method_retryable(self, settings, request, response=None):
        """Checks if a given HTTP method should be retried upon, depending if
        it is included on the method whitelist.

        :param dict settings: The retry settings.
        :param request: The PipelineRequest object.
        :type request: ~azure.core.pipeline.PipelineRequest
        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :return: True if method should be retried upon. False if not in method whitelist.
        :rtype: bool
        """
        if response and request.method.upper() in ['POST', 'PATCH'] and \
                response.status_code in [500, 503, 504]:
            return True
        if request.method.upper() not in settings['methods']:
            return False

        return True

    def is_retry(self, settings, response):
        """Checks if method/status code is retryable.

        Based on whitelists and control variables such as the number of
        total retries to allow, whether to respect the Retry-After header,
        whether this header is present, and whether the returned status
        code is on the list of status codes to be retried upon on the
        presence of the aforementioned header.

        :param dict settings: The retry settings.
        :param response: The PipelineResponse object
        :type response: ~azure.core.pipeline.PipelineResponse.
        :return: True if method/status code is retryable. False if not retryable.
        :rtype: bool
        """
        has_retry_after = bool(response.http_response.headers.get("Retry-After"))
        if has_retry_after and self._respect_retry_after_header:
            return True
        if not self._is_method_retryable(settings, response.http_request, response=response.http_response):
            return False
        return settings['total'] and response.http_response.status_code in self._retry_on_status_codes

    def is_exhausted(self, settings):
        """Checks if any retries left.

        :param dict settings: the retry settings
        :return: False if have more retries. True if retries exhausted.
        :rtype: bool
        """
        retry_counts = (settings['total'], settings['connect'], settings['read'], settings['status'])
        retry_counts = list(filter(None, retry_counts))
        if not retry_counts:
            return False

        return min(retry_counts) < 0

    def increment(self, settings, response=None, error=None):
        """Increment the retry counters.

        :param settings: The retry settings.
        :param response: A pipeline response object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :param error: An error encountered during the request, or
         None if the response was received successfully.
        :return: Whether the retry attempts are exhausted.
         False if exhausted; True if more retry attempts available.
        :rtype: bool
        """
        settings['total'] -= 1

        if error and self._is_connection_error(error):
            # Connect retry?
            settings['connect'] -= 1
            settings['history'].append(RequestHistory(response.http_request, error=error))

        elif error and self._is_read_error(error):
            # Read retry?
            settings['read'] -= 1
            settings['history'].append(RequestHistory(response.http_request, error=error))

        else:
            # Incrementing because of a server error like a 500 in
            # status_forcelist and a the given method is in the whitelist
            if response:
                settings['status'] -= 1
                settings['history'].append(RequestHistory(response.http_request, http_response=response.http_response))

        return not self.is_exhausted(settings)

    def update_context(self, context, retry_settings):
        """Updates retry history in pipeline context.

        :param context: The pipeline context.
        :type context: ~azure.core.pipeline.PipelineContext
        :param retry_settings: The retry settings.
        :type retry_settings: dict
        """
        if retry_settings['history']:
            context['history'] = retry_settings['history']

    def send(self, request):
        """Sends the PipelineRequest object to the next policy.
         Uses retry settings if necessary.

        :param request: The PipelineRequest object
        :type request: ~azure.core.pipeline.PipelineRequest
        :return: Returns the PipelineResponse or raises error if maximum retries exceeded.
        :rtype: ~azure.core.pipeline.PipelineResponse
        :raises: ~azure.core.exceptions.AzureError if maximum retries exceeded.
        """
        retry_active = True
        response = None
        retry_settings = self.configure_retries(request.context.options)
        while retry_active:
            try:
                response = self.next.send(request)
                if self.is_retry(retry_settings, response):
                    retry_active = self.increment(retry_settings, response=response)
                    if retry_active:
                        self.sleep(retry_settings, request.context.transport, response=response)
                        continue
                break
            except AzureError as err:
                if self._is_method_retryable(retry_settings, request.http_request):
                    retry_active = self.increment(retry_settings, response=request, error=err)
                    if retry_active:
                        self.sleep(retry_settings, request.context.transport)
                        continue
                raise err

        self.update_context(response.context, retry_settings)
        return response
<commit_msg>fixes retry bug on 202 status code (#5669)<commit_after>#pylint: disable=no-self-use
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------
"""
This module is the requests implementation of Pipeline ABC
"""
from __future__ import absolute_import  # we have a "requests" module that conflicts with "requests" on Py2.7
import logging
import time
import email
from typing import TYPE_CHECKING, List, Callable, Iterator, Any, Union, Dict, Optional  # pylint: disable=unused-import

from azure.core.exceptions import (
    AzureError,
    ServiceResponseError,
    ServiceRequestError
)

from .base import HTTPPolicy, RequestHistory

_LOGGER = logging.getLogger(__name__)

class RetryPolicy(HTTPPolicy):
    """A retry policy.

    The retry policy in the pipeline can be configured directly, or tweaked on a per-call basis.

    Keyword arguments:
    :param int retry_total: Total number of retries to allow. Takes precedence over other counts.
     Default value is 10.
    :param int retry_connect: How many connection-related errors to retry on.
     These are errors raised before the request is sent to the remote server,
     which we assume has not triggered the server to process the request. Default value is 3.
    :param int retry_read: How many times to retry on read errors.
     These errors are raised after the request was sent to the server, so the
     request may have side-effects. Default value is 3.
    :param int retry_status: How many times to retry on bad status codes. Default value is 3.
    :param int retry_backoff_factor: A backoff factor to apply between attempts after the second try
     (most errors are resolved immediately by a second try without a delay).
     Retry policy will sleep for: `{backoff factor} * (2 ** ({number of total retries} - 1))`
     seconds. If the backoff_factor is 0.1, then the retry will sleep
     for [0.0s, 0.2s, 0.4s, ...] between retries. The default value is 0.8.
    :param int retry_backoff_max: The maximum back off time. Default value is 120 seconds (2 minutes).

    Example:
        .. literalinclude:: ../../../../examples/examples_sync.py
            :start-after: [START retry_policy]
            :end-before: [END retry_policy]
            :language: python
            :dedent: 4
            :caption: Configuring a retry policy.
    """

    #: Maximum backoff time.
    BACKOFF_MAX = 120

    def __init__(self, **kwargs):
        self.total_retries = kwargs.pop('retry_total', 10)
        self.connect_retries = kwargs.pop('retry_connect', 3)
        self.read_retries = kwargs.pop('retry_read', 3)
        self.status_retries = kwargs.pop('retry_status', 3)
        self.backoff_factor = kwargs.pop('retry_backoff_factor', 0.8)
        self.backoff_max = kwargs.pop('retry_backoff_max', self.BACKOFF_MAX)

        safe_codes = [i for i in range(500) if i != 408] + [501, 505]
        retry_codes = [i for i in range(999) if i not in safe_codes]
        status_codes = kwargs.pop('retry_on_status_codes', [])
        self._retry_on_status_codes = set(status_codes + retry_codes)
        self._method_whitelist = frozenset(['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'])
        self._respect_retry_after_header = True
        super(RetryPolicy, self).__init__()

    @classmethod
    def no_retries(cls):
        """Disable retries.
        """
        return cls(retry_count_total=0)

    def configure_retries(self, options):
        """Configures the retry settings.

        :param options: keyword arguments from context.
        :return: A dict containing settings and history for retries.
        :rtype: dict
        """
        return {
            'total': options.pop("retry_total", self.total_retries),
            'connect': options.pop("retry_connect", self.connect_retries),
            'read': options.pop("retry_read", self.read_retries),
            'status': options.pop("retry_status", self.status_retries),
            'backoff': options.pop("retry_backoff_factor", self.backoff_factor),
            'max_backoff': options.pop("retry_backoff_max", self.BACKOFF_MAX),
            'methods': options.pop("retry_on_methods", self._method_whitelist),
            'history': []
        }

    def get_backoff_time(self, settings):
        """Returns the current backoff time.

        :param dict settings: The retry settings.
        :return: The current backoff value.
        :rtype: float
        """
        # We want to consider only the last consecutive errors sequence (Ignore redirects).
        consecutive_errors_len = len(settings['history'])
        if consecutive_errors_len <= 1:
            return 0

        backoff_value = settings['backoff'] * (2 ** (consecutive_errors_len - 1))
        return min(settings['max_backoff'], backoff_value)

    def parse_retry_after(self, retry_after):
        """Helper to parse Retry-After and get value in seconds.

        :param str retry_after: Retry-After header
        :rtype: int
        """
        try:
            seconds = int(retry_after)
        except TypeError:
            retry_date_tuple = email.utils.parsedate(retry_after)
            if retry_date_tuple is None:
                return None
            retry_date = time.mktime(retry_date_tuple)
            seconds = retry_date - time.time()

        if seconds < 0:
            seconds = 0
        return seconds

    def get_retry_after(self, response):
        """Get the value of Retry-After in seconds.

        :param response: The PipelineResponse object
        :type response: ~azure.core.pipeline.PipelineResponse
        :return: Value of Retry-After in seconds.
        :rtype: int
        """
        retry_after = response.http_response.headers.get("Retry-After")
        if retry_after is None:
            return None
        return self.parse_retry_after(retry_after)

    def _sleep_for_retry(self, response, transport):
        """Sleep based on the Retry-After response header value.

        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :param transport: The HTTP transport type.
        """
        retry_after = self.get_retry_after(response)
        if retry_after:
            transport.sleep(retry_after)
            return True
        return False

    def _sleep_backoff(self, settings, transport):
        """Sleep using exponential backoff. Immediately returns if backoff is 0.

        :param dict settings: The retry settings.
        :param transport: The HTTP transport type.
        """
        backoff = self.get_backoff_time(settings)
        if backoff <= 0:
            return
        transport.sleep(backoff)

    def sleep(self, settings, transport, response=None):
        """Sleep between retry attempts.

        This method will respect a server's ``Retry-After`` response header
        and sleep the duration of the time requested. If that is not present, it
        will use an exponential backoff. By default, the backoff factor is 0 and
        this method will return immediately.

        :param dict settings: The retry settings.
        :param transport: The HTTP transport type.
        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        """
        if response:
            slept = self._sleep_for_retry(response, transport)
            if slept:
                return
        self._sleep_backoff(settings, transport)

    def _is_connection_error(self, err):
        """Errors when we're fairly sure that the server did not receive the
        request, so it should be safe to retry.
        """
        return isinstance(err, ServiceRequestError)

    def _is_read_error(self, err):
        """Errors that occur after the request has been started, so we should
        assume that the server began processing it.
        """
        return isinstance(err, ServiceResponseError)

    def _is_method_retryable(self, settings, request, response=None):
        """Checks if a given HTTP method should be retried upon, depending if
        it is included on the method whitelist.

        :param dict settings: The retry settings.
        :param request: The PipelineRequest object.
        :type request: ~azure.core.pipeline.PipelineRequest
        :param response: The PipelineResponse object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :return: True if method should be retried upon. False if not in method whitelist.
        :rtype: bool
        """
        if response and request.method.upper() in ['POST', 'PATCH'] and \
                response.status_code in [500, 503, 504]:
            return True
        if request.method.upper() not in settings['methods']:
            return False

        return True

    def is_retry(self, settings, response):
        """Checks if method/status code is retryable.

        Based on whitelists and control variables such as the number of
        total retries to allow, whether to respect the Retry-After header,
        whether this header is present, and whether the returned status
        code is on the list of status codes to be retried upon on the
        presence of the aforementioned header.

        :param dict settings: The retry settings.
        :param response: The PipelineResponse object
        :type response: ~azure.core.pipeline.PipelineResponse.
        :return: True if method/status code is retryable. False if not retryable.
        :rtype: bool
        """
        has_retry_after = bool(response.http_response.headers.get("Retry-After"))
        if has_retry_after and self._respect_retry_after_header:
            return True
        if not self._is_method_retryable(settings, response.http_request, response=response.http_response):
            return False
        return settings['total'] and response.http_response.status_code in self._retry_on_status_codes

    def is_exhausted(self, settings):
        """Checks if any retries left.

        :param dict settings: the retry settings
        :return: False if have more retries. True if retries exhausted.
        :rtype: bool
        """
        retry_counts = (settings['total'], settings['connect'], settings['read'], settings['status'])
        retry_counts = list(filter(None, retry_counts))
        if not retry_counts:
            return False

        return min(retry_counts) < 0

    def increment(self, settings, response=None, error=None):
        """Increment the retry counters.

        :param settings: The retry settings.
        :param response: A pipeline response object.
        :type response: ~azure.core.pipeline.PipelineResponse
        :param error: An error encountered during the request, or
         None if the response was received successfully.
        :return: Whether the retry attempts are exhausted.
         False if exhausted; True if more retry attempts available.
        :rtype: bool
        """
        settings['total'] -= 1

        if response.http_response.status_code == 202:
            return False

        if error and self._is_connection_error(error):
            # Connect retry?
            settings['connect'] -= 1
            settings['history'].append(RequestHistory(response.http_request, error=error))

        elif error and self._is_read_error(error):
            # Read retry?
            settings['read'] -= 1
            settings['history'].append(RequestHistory(response.http_request, error=error))

        else:
            # Incrementing because of a server error like a 500 in
            # status_forcelist and a the given method is in the whitelist
            if response:
                settings['status'] -= 1
                settings['history'].append(RequestHistory(response.http_request, http_response=response.http_response))

        return not self.is_exhausted(settings)

    def update_context(self, context, retry_settings):
        """Updates retry history in pipeline context.

        :param context: The pipeline context.
        :type context: ~azure.core.pipeline.PipelineContext
        :param retry_settings: The retry settings.
        :type retry_settings: dict
        """
        if retry_settings['history']:
            context['history'] = retry_settings['history']

    def send(self, request):
        """Sends the PipelineRequest object to the next policy.
         Uses retry settings if necessary.

        :param request: The PipelineRequest object
        :type request: ~azure.core.pipeline.PipelineRequest
        :return: Returns the PipelineResponse or raises error if maximum retries exceeded.
        :rtype: ~azure.core.pipeline.PipelineResponse
        :raises: ~azure.core.exceptions.AzureError if maximum retries exceeded.
        """
        retry_active = True
        response = None
        retry_settings = self.configure_retries(request.context.options)
        while retry_active:
            try:
                response = self.next.send(request)
                if self.is_retry(retry_settings, response):
                    retry_active = self.increment(retry_settings, response=response)
                    if retry_active:
                        self.sleep(retry_settings, request.context.transport, response=response)
                        continue
                break
            except AzureError as err:
                if self._is_method_retryable(retry_settings, request.http_request):
                    retry_active = self.increment(retry_settings, response=request, error=err)
                    if retry_active:
                        self.sleep(retry_settings, request.context.transport)
                        continue
                raise err

        self.update_context(response.context, retry_settings)
        return response
<|endoftext|>


<commit_before>""" Concise UUID generation. """

import binascii
import math
import os
import uuid as _uu

def int_to_string(number, alphabet, padding=None):
    """
    Convert a number to a string, using the given alphabet.
    """
    output = ""
    alpha_len = len(alphabet)
    while number:
        number, digit = divmod(number, alpha_len)
        output += alphabet[digit]
    if padding:
        remainder = max(padding - len(output), 0)
        output = output + alphabet[0] * remainder
    return output

def string_to_int(string, alphabet):
    """
    Convert a string to a number, using the given alphabet.
    """
    number = 0
    alpha_len = len(alphabet)
    for char in string[::-1]:
        number = number * alpha_len + alphabet.index(char)
    return number

class ShortUUID(object):
    def __init__(self, alphabet=None):
        if alphabet is None:
            alphabet = list("23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
                            "abcdefghijkmnopqrstuvwxyz")

        self.set_alphabet(alphabet)

    @property
    def _length(self):
        """
        Return the necessary length to fit the entire UUID given
        the current alphabet.
        """
        return int(math.ceil(math.log(2 ** 128, self._alpha_len)))

    def encode(self, uuid, pad_length=None):
        """
        Encodes a UUID into a string (LSB first) according to the alphabet
        If leftmost (MSB) bits 0, string might be shorter
        """
        if pad_length is None:
            pad_length = self._length
        return int_to_string(uuid.int, self._alphabet, padding=pad_length)

    def decode(self, string):
        """
        Decodes a string according to the current alphabet into a UUID
        Raises ValueError when encountering illegal characters
        or too long string
        If string too short, fills leftmost (MSB) bits with 0.
        """
        return _uu.UUID(int=string_to_int(string, self._alphabet))

    def uuid(self, name=None, pad_length=None):
        """
        Generate and return a UUID.

        If the name parameter is provided, set the namespace to the provided
        name and generate a UUID.
        """
        if pad_length is None:
            pad_length = self._length

        # If no name is given, generate a random UUID.
        if name is None:
            uuid = _uu.uuid4()
        elif "http" not in name.lower():
            uuid = _uu.uuid5(_uu.NAMESPACE_DNS, name)
        else:
            uuid = _uu.uuid5(_uu.NAMESPACE_URL, name)
        return self.encode(uuid, pad_length)

    def random(self, length=None):
        """
        Generate and return a cryptographically-secure short random string
        of the specified length.
        """
        if length is None:
            length = self._length

        random_num = int(binascii.b2a_hex(os.urandom(length)), 16)
        return int_to_string(
            random_num, self._alphabet, padding=length
        )[:length]

    def get_alphabet(self):
        """Return the current alphabet used for new UUIDs."""
        return ''.join(self._alphabet)

    def set_alphabet(self, alphabet):
        """Set the alphabet to be used for new UUIDs."""

        # Turn the alphabet into a set and sort it to prevent duplicates
        # and ensure reproducibility.
        new_alphabet = list(sorted(set(alphabet)))
        if len(new_alphabet) > 1:
            self._alphabet = new_alphabet
            self._alpha_len = len(self._alphabet)
        else:
            raise ValueError("Alphabet with more than "
                             "one unique symbols required.")

    def encoded_length(self, num_bytes=16):
        """
        Returns the string length of the shortened UUID.
        """
        factor = math.log(256) / math.log(self._alpha_len)
        return int(math.ceil(factor * num_bytes))

# For backwards compatibility
_global_instance = ShortUUID()
encode = _global_instance.encode
decode = _global_instance.decode
uuid = _global_instance.uuid
random = _global_instance.random
get_alphabet = _global_instance.get_alphabet
set_alphabet = _global_instance.set_alphabet
<commit_msg>fix: Make the URL check more robust (fixes #32)<commit_after>""" Concise UUID generation. """

import binascii
import math
import os
import uuid as _uu

def int_to_string(number, alphabet, padding=None):
    """
    Convert a number to a string, using the given alphabet.
    """
    output = ""
    alpha_len = len(alphabet)
    while number:
        number, digit = divmod(number, alpha_len)
        output += alphabet[digit]
    if padding:
        remainder = max(padding - len(output), 0)
        output = output + alphabet[0] * remainder
    return output

def string_to_int(string, alphabet):
    """
    Convert a string to a number, using the given alphabet.
    """
    number = 0
    alpha_len = len(alphabet)
    for char in string[::-1]:
        number = number * alpha_len + alphabet.index(char)
    return number

class ShortUUID(object):
    def __init__(self, alphabet=None):
        if alphabet is None:
            alphabet = list("23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
                            "abcdefghijkmnopqrstuvwxyz")

        self.set_alphabet(alphabet)

    @property
    def _length(self):
        """
        Return the necessary length to fit the entire UUID given
        the current alphabet.
        """
        return int(math.ceil(math.log(2 ** 128, self._alpha_len)))

    def encode(self, uuid, pad_length=None):
        """
        Encodes a UUID into a string (LSB first) according to the alphabet
        If leftmost (MSB) bits 0, string might be shorter
        """
        if pad_length is None:
            pad_length = self._length
        return int_to_string(uuid.int, self._alphabet, padding=pad_length)

    def decode(self, string):
        """
        Decodes a string according to the current alphabet into a UUID
        Raises ValueError when encountering illegal characters
        or too long string
        If string too short, fills leftmost (MSB) bits with 0.
        """
        return _uu.UUID(int=string_to_int(string, self._alphabet))

    def uuid(self, name=None, pad_length=None):
        """
        Generate and return a UUID.

        If the name parameter is provided, set the namespace to the provided
        name and generate a UUID.
        """
        if pad_length is None:
            pad_length = self._length

        # If no name is given, generate a random UUID.
        if name is None:
            uuid = _uu.uuid4()
        elif name.lower().startswith(("http://", "https://")):
            uuid = _uu.uuid5(_uu.NAMESPACE_URL, name)
        else:
            uuid = _uu.uuid5(_uu.NAMESPACE_DNS, name)
        return self.encode(uuid, pad_length)

    def random(self, length=None):
        """
        Generate and return a cryptographically-secure short random string
        of the specified length.
        """
        if length is None:
            length = self._length

        random_num = int(binascii.b2a_hex(os.urandom(length)), 16)
        return int_to_string(
            random_num, self._alphabet, padding=length
        )[:length]

    def get_alphabet(self):
        """Return the current alphabet used for new UUIDs."""
        return ''.join(self._alphabet)

    def set_alphabet(self, alphabet):
        """Set the alphabet to be used for new UUIDs."""

        # Turn the alphabet into a set and sort it to prevent duplicates
        # and ensure reproducibility.
        new_alphabet = list(sorted(set(alphabet)))
        if len(new_alphabet) > 1:
            self._alphabet = new_alphabet
            self._alpha_len = len(self._alphabet)
        else:
            raise ValueError("Alphabet with more than "
                             "one unique symbols required.")

    def encoded_length(self, num_bytes=16):
        """
        Returns the string length of the shortened UUID.
        """
        factor = math.log(256) / math.log(self._alpha_len)
        return int(math.ceil(factor * num_bytes))

# For backwards compatibility
_global_instance = ShortUUID()
encode = _global_instance.encode
decode = _global_instance.decode
uuid = _global_instance.uuid
random = _global_instance.random
get_alphabet = _global_instance.get_alphabet
set_alphabet = _global_instance.set_alphabet
<|endoftext|>


<commit_before>""" Concise UUID generation. """

import binascii
import math
import os
import uuid as _uu

class ShortUUID(object):
    def __init__(self, alphabet=None):
        if alphabet is None:
            alphabet = list("23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
                            "abcdefghijkmnopqrstuvwxyz")

        self.set_alphabet(alphabet)

    @property
    def _length(self):
        """
        Return the necessary length to fit the entire UUID given
        the current alphabet.
        """
        return int(math.ceil(math.log(2 ** 128, self._alpha_len)))

    def _num_to_string(self, number, pad_to_length=None):
        """
        Convert a number to a string, using the given alphabet.
        """
        output = ""
        while number:
            number, digit = divmod(number, self._alpha_len)
            output += self._alphabet[digit]
        if pad_to_length:
            remainder = max(pad_to_length - len(output), 0)
            output = output + self._alphabet[0] * remainder
        return output

    def _string_to_int(self, string):
        """
        Convert a string to a number, using the given alphabet..
        """
        number = 0
        for char in string[::-1]:
            number = number * self._alpha_len + self._alphabet.index(char)
        return number

    def encode(self, uuid, pad_length=None):
        """
        Encodes a UUID into a string (LSB first) according to the alphabet
        If leftmost (MSB) bits 0, string might be shorter
        """
        if pad_length is None:
            pad_length = self._length
        return self._num_to_string(uuid.int, pad_to_length=pad_length)

    def decode(self, string):
        """
        Decodes a string according to the current alphabet into a UUID
        Raises ValueError when encountering illegal characters
        or too long string
        If string too short, fills leftmost (MSB) bits with 0.
        """
        return _uu.UUID(int=self._string_to_int(string))

    def uuid(self, name=None, pad_length=None):
        """
        Generate and return a UUID.

        If the name parameter is provided, set the namespace to the provided
        name and generate a UUID.
        """
        if pad_length is None:
            pad_length = self._length

        # If no name is given, generate a random UUID.
        if name is None:
            uuid = _uu.uuid4()
        elif "http" not in name.lower():
            uuid = _uu.uuid5(_uu.NAMESPACE_DNS, name)
        else:
            uuid = _uu.uuid5(_uu.NAMESPACE_URL, name)
        return self.encode(uuid, pad_length)

    def random(self, length=None):
        """
        Generate and return a cryptographically-secure short random string
        of the specified length.
        """
        if length is None:
            length = self._length

        random_num = int(binascii.b2a_hex(os.urandom(length)), 16)
        return self._num_to_string(random_num, pad_to_length=length)[:length]

    def get_alphabet(self):
        """Return the current alphabet used for new UUIDs."""
        return ''.join(self._alphabet)

    def set_alphabet(self, alphabet):
        """Set the alphabet to be used for new UUIDs."""

        # Turn the alphabet into a set and sort it to prevent duplicates
        # and ensure reproducibility.
        new_alphabet = list(sorted(set(alphabet)))
        if len(new_alphabet) > 1:
            self._alphabet = new_alphabet
            self._alpha_len = len(self._alphabet)
        else:
            raise ValueError("Alphabet with more than "
                             "one unique symbols required.")

    def encoded_length(self, num_bytes=16):
        """
        Returns the string length of the shortened UUID.
        """
        factor = math.log(256) / math.log(self._alpha_len)
        return int(math.ceil(factor * num_bytes))

# For backwards compatibility
_global_instance = ShortUUID()
encode = _global_instance.encode
decode = _global_instance.decode
uuid = _global_instance.uuid
random = _global_instance.random
get_alphabet = _global_instance.get_alphabet
set_alphabet = _global_instance.set_alphabet
<commit_msg>Make int_to_string and string_to_int available globally<commit_after>""" Concise UUID generation. """

import binascii
import math
import os
import uuid as _uu

def int_to_string(number, alphabet, padding=None):
    """
    Convert a number to a string, using the given alphabet.
    """
    output = ""
    alpha_len = len(alphabet)
    while number:
        number, digit = divmod(number, alpha_len)
        output += alphabet[digit]
    if padding:
        remainder = max(padding - len(output), 0)
        output = output + alphabet[0] * remainder
    return output

def string_to_int(string, alphabet):
    """
    Convert a string to a number, using the given alphabet.
    """
    number = 0
    alpha_len = len(alphabet)
    for char in string[::-1]:
        number = number * alpha_len + alphabet.index(char)
    return number

class ShortUUID(object):
    def __init__(self, alphabet=None):
        if alphabet is None:
            alphabet = list("23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
                            "abcdefghijkmnopqrstuvwxyz")

        self.set_alphabet(alphabet)

    @property
    def _length(self):
        """
        Return the necessary length to fit the entire UUID given
        the current alphabet.
        """
        return int(math.ceil(math.log(2 ** 128, self._alpha_len)))

    def encode(self, uuid, pad_length=None):
        """
        Encodes a UUID into a string (LSB first) according to the alphabet
        If leftmost (MSB) bits 0, string might be shorter
        """
        if pad_length is None:
            pad_length = self._length
        return int_to_string(uuid.int, self._alphabet, padding=pad_length)

    def decode(self, string):
        """
        Decodes a string according to the current alphabet into a UUID
        Raises ValueError when encountering illegal characters
        or too long string
        If string too short, fills leftmost (MSB) bits with 0.
        """
        return _uu.UUID(int=string_to_int(string, self._alphabet))

    def uuid(self, name=None, pad_length=None):
        """
        Generate and return a UUID.

        If the name parameter is provided, set the namespace to the provided
        name and generate a UUID.
        """
        if pad_length is None:
            pad_length = self._length

        # If no name is given, generate a random UUID.
        if name is None:
            uuid = _uu.uuid4()
        elif "http" not in name.lower():
            uuid = _uu.uuid5(_uu.NAMESPACE_DNS, name)
        else:
            uuid = _uu.uuid5(_uu.NAMESPACE_URL, name)
        return self.encode(uuid, pad_length)

    def random(self, length=None):
        """
        Generate and return a cryptographically-secure short random string
        of the specified length.
        """
        if length is None:
            length = self._length

        random_num = int(binascii.b2a_hex(os.urandom(length)), 16)
        return int_to_string(
            random_num, self._alphabet, padding=length
        )[:length]

    def get_alphabet(self):
        """Return the current alphabet used for new UUIDs."""
        return ''.join(self._alphabet)

    def set_alphabet(self, alphabet):
        """Set the alphabet to be used for new UUIDs."""

        # Turn the alphabet into a set and sort it to prevent duplicates
        # and ensure reproducibility.
        new_alphabet = list(sorted(set(alphabet)))
        if len(new_alphabet) > 1:
            self._alphabet = new_alphabet
            self._alpha_len = len(self._alphabet)
        else:
            raise ValueError("Alphabet with more than "
                             "one unique symbols required.")

    def encoded_length(self, num_bytes=16):
        """
        Returns the string length of the shortened UUID.
        """
        factor = math.log(256) / math.log(self._alpha_len)
        return int(math.ceil(factor * num_bytes))

# For backwards compatibility
_global_instance = ShortUUID()
encode = _global_instance.encode
decode = _global_instance.decode
uuid = _global_instance.uuid
random = _global_instance.random
get_alphabet = _global_instance.get_alphabet
set_alphabet = _global_instance.set_alphabet
<|endoftext|>


<commit_before>from django.http import HttpResponse
from django.template import RequestContext, Context, loader
from django.shortcuts import redirect, render
from django.db import transaction

from djangobb_forum.util import render_to

from shoutbox.models import ShoutboxEntry
from shoutbox.forms import ShoutboxPostForm

def recent_entries(request, entrycount=5):
    """Render a set of recent entries"""
    entries = ShoutboxEntry.objects.order_by('-created')[:entrycount]
    return render(request, 'shoutbox/recents.html', {'entries':entries})

@transaction.commit_on_success
def postform(request):
    if request.method == 'POST':
        form = ShoutboxPostForm(request.POST)

        if request.user.is_authenticated():
            del form.fields['hint']

        if form.is_valid():
            entry = ShoutboxEntry()
            entry.text = form.cleaned_data['message']
            entry.ip = request.META['REMOTE_ADDR']
            if request.user.is_authenticated():
                entry.author = request.user
                entry.author_name = request.user.username
            else:
                entry.author = None
                entry.author_name = form.cleaned_data['nickname']
            entry.save()
            if request.is_ajax():
                # For ajax store, send a blank, new form afterwards
                form = ShoutboxPostForm()
                if request.user.is_authenticated():
                    del form.fields['hint']
            else:
                next = request.POST['next'] or request.META['HTTP_REFERER']
                if next and next == "/shoutbox/post":
                    next = "/"
                return redirect(next if next else '/')
    else:
        form = ShoutboxPostForm()
        form.fields['next'].initial=request.get_full_path()
        if request.user.is_authenticated():
            form.fields['nickname'].initial = request.user.username
            del form.fields['hint']

    return render(request, 'shoutbox/postform.html',
                           {'form':form})
<commit_msg>Tag nickname readonly for logged in users, it will be replaced on post either way<commit_after>from django.http import HttpResponse
from django.template import RequestContext, Context, loader
from django.shortcuts import redirect, render
from django.db import transaction

from djangobb_forum.util import render_to

from shoutbox.models import ShoutboxEntry
from shoutbox.forms import ShoutboxPostForm

def recent_entries(request, entrycount=5):
    """Render a set of recent entries"""
    entries = ShoutboxEntry.objects.order_by('-created')[:entrycount]
    return render(request, 'shoutbox/recents.html', {'entries':entries})

@transaction.commit_on_success
def postform(request):
    if request.method == 'POST':
        form = ShoutboxPostForm(request.POST)

        if request.user.is_authenticated():
            del form.fields['hint']

        if form.is_valid():
            entry = ShoutboxEntry()
            entry.text = form.cleaned_data['message']
            entry.ip = request.META['REMOTE_ADDR']
            if request.user.is_authenticated():
                entry.author = request.user
                entry.author_name = request.user.username
            else:
                entry.author = None
                entry.author_name = form.cleaned_data['nickname']
            entry.save()
            if request.is_ajax():
                # For ajax store, send a blank, new form afterwards
                form = ShoutboxPostForm()
                if request.user.is_authenticated():
                    del form.fields['hint']
            else:
                next = request.POST['next'] or request.META['HTTP_REFERER']
                if next and next == "/shoutbox/post":
                    next = "/"
                return redirect(next if next else '/')
    else:
        form = ShoutboxPostForm()
        form.fields['next'].initial=request.get_full_path()
        if request.user.is_authenticated():
            form.fields['nickname'].initial = request.user.username
            form.fields['nickname'].widget.attrs['readonly'] = True
            del form.fields['hint']

    return render(request, 'shoutbox/postform.html',
                           {'form':form})
<|endoftext|>


<commit_before>from . import BrTestCase, dots

class Regressions(BrTestCase):
  def pairs(self):
    return (
	('was.', dots('356 256')),
	('but-this', dots('12 36 1456')),
	)

<commit_msg>Added regression tests for:<commit_after>from . import BrTestCase, dots

class Regressions(BrTestCase):
  def pairs(self):
    return (
	'refined match for wcells: 145b9f642ec083bdf25b25268dfa1bc33a4dadc2',
	('was.', dots('356 256')),
	('but-this', dots('12 36 1456')),
	'Abbrevs should be translated before prefixes 0f427bb2294e6f773e872d67d95b2c41153dfbe4',
	('today', dots('2345 145')),
	)

<|endoftext|>


<commit_before>import time
import grovepi
import atexit
import json
import sys
import logging

import argparse

from datetime import datetime

# get import working from a directory
from sensorvalue import SensorValue
from sensorconfig import SensorConfig
import notifier

from config import settings

def main():

    # two collections that really matter
    #one is the list of sensors that are supported by this code.
    supportedsensors = ['loudness', 'airquality', 'gas', 'tempandhumidity']

    sensorconfig = SensorConfig(settings)

    #two is the list of sensors configured in the settings.yaml file

    if not sensorconfig.isconfigvalid(supportedsensors):
        print 'Configuration is invalid'
        return

    sensordatafile = getsensorfilename()

    parser = argparse.ArgumentParser(description='Use this to poll sensor data from raspberry pi and the grove pi')
    parser.add_argument(
        '-p', '--poll', help='Poll all sensors in the config file at the configured interval', action='store_true')

    parser.add_argument('-s', '--sensortest', help='Name of the sensor to test. Supported sensors: ' + str(supportedsensors), default='nosensor')

    parser.add_argument('-m', '--mock', help='Do a mock sensor test', action='store_true')
    parser.add_argument('-n', '--notify', help='Perform a notification test', action='store_true')

    args = vars(parser.parse_args())

    parser.print_usage()

    mockingmode = False
    if args['mock']:
        mockingmode = True

    # if args['notify']:
    #     notifier.sendnotification("Test message",  "Test subject")

    if args['poll']:
            startautopolling(sensorconfig.configuredsensors, mockingmode, sensorconfig)

    if args['sensortest'] in supportedsensors:
        sensordata = getsensordata(args['sensortest'], mockingmode, sensorconfig)

        if sensordata != None:
            for data in sensordata:
                if data == None:
                    print 'No data was returned by the sensor'
                else:
                    print data.yaml()

    if args['sensortest'] in ['nosensor'] and args['sensortest'] not in supportedsensors:
        print 'the sensor ' +  args['sensortest'] + ' is not supported'
        print 'currently using a dictionary called supportedsensors at the top of this file to manage this list'
        print 'supported sensors: ' + str(supportedsensors)

    # The all case loops through all of the configured sensors and prints out there values
    if args['sensortest'] == "all":
        print "Looping through the sensors " + str(sensorconfig.configuredsensors)
        for item in sensorconfig.configuredsensors:
            data = getsensordata(item, mockingmode, sensorconfig)

            if data == None:
                print "No Data was returned"
                print "Exiting...."
                return

            for item in data:
                print item.yaml()

def getsensorconfig(sensorname):
    if sensorname in settings.keys():
        print sensorname + " is configured for port " + str(settings[sensorname]["port"])

        return settings[sensorname]["port"]
    else:
        print "missing config value for " + sensorname
        return

def getsensordata(sensorname, enablemocking, sensorconfig):

    if enablemocking:
        return

    try:

        if sensorname == "loudness":
            return getloudnessinfo(sensorname)
        if sensorname == "airquality":
            return getairqualitysensorvalue(sensorname)
        if sensorname == "gas":
            return getgassensorvalue(sensorname)
        if sensorname == "tempandhumidity":
            return gettempandhumidity(sensorname)
        if sensorname == "dust":
            return readdustsensor(sensorname)

    except:
        print sys.exc_info()[0]

def startautopolling(configuredsensors, enablemocking, sensorconfig):

    print "Starting to Autopoll the sensors"
    pollinginterval = settings["core"]["pollinginterval"]
    sensordatafile = getsensorfilename()

    #start the polling loop
    while True:
        if pollinginterval != settings["core"]["pollinginterval"]:
            print "polling interval changed from " + str(pollinginterval) + " to " + settings["core"]["pollinginterval"]
            pollinginterval = settings["core"]["pollinginterval"]

        #check for a new polling interval
        values = []

        for item in configuredsensors:
            sensorvalue = getsensordata(item, enablemocking)
            if sensorvalue != None:
                values.append(sensorvalue)

        writetofile(values, sensordatafile)

        time.sleep(pollinginterval)

        # getairqualitysensorvalue()
        # getgassensorvalue(location, gas_sensor_pin)
        # https://github.com/DexterInd/GrovePi/blob/master/Software/Python/grove_gas_sensor.py

def writetofile(data, sensordatafile):
    with open(sensordatafile, 'ab') as f:
        for items in data:
            for item in items:
                f.write(item.writecsv() + '\n')

def getsensorfilename():
    return "sensorlog" + datetime.now().strftime('%Y%m%d%H%M%S') + ".log"

def readdustsensor(sensorname):

    sensordata = []

    pin = getsensorconfig(sensorname)

    atexit.register(grovepi.dust_sensor_dis)

    print("Reading from the dust sensor")
    grovepi.dust_sensor_en()

    try:
                [new_val,lowpulseoccupancy] = grovepi.dustSensorRead()

                print "new_val: " + str(new_val)
                print "lowpulseoccupancy: " + str(lowpulseoccupancy)

                if new_val:
                    print(lowpulseoccupancy)
                    sensordata.append(SensorValue(lowpulseoccupancy, 'none', 'Dust', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def gettempandhumidity(sensorname):

    pin = getsensorconfig(sensorname)
    dht_sensor_type = 0             # change this depending on your sensor type - see header comment

    try:
        [temp,humidity] = grovepi.dht(pin,dht_sensor_type)
        print "temp =", temp, " humidity =", humidity

        sensordata = []
        sensordata.append(SensorValue(temp, 'none', 'temp', 'location'))
        sensordata.append(SensorValue(humidity, 'none', 'humidity', 'location'))

    except IOError:
        print "Error"
    return sensordata

def getloudnessinfo(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)
    try:
        # Read the sound level
        sensor_value = grovepi.analogRead(pin)
        sensordata.append(SensorValue(sensor_value, 'none', 'Loudness', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def getgassensorvalue(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)

    grovepi.pinMode(pin,"INPUT")
    try:
        # Get sensor value
        sensor_value = grovepi.analogRead(pin)

        # Calculate gas density - large value means more dense gas
        density = (float)(sensor_value / 1024)
        sensordata.append(SensorValue(sensor_value, 'none', 'Gas', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def getairqualitysensorvalue(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)

    grovepi.pinMode(pin,"INPUT")

    try:
        # Get sensor value
        sensor_value = grovepi.analogRead(pin)

        if sensor_value > 700:
            print ("High pollution")
        elif sensor_value > 300:
            print ("Low pollution")
        else:
            print ("Air fresh")
        sensordata.append(SensorValue(sensor_value, 'none', 'airquality', 'location'))
    except IOError:
        print ("Error")

    return sensordata

if __name__ == '__main__':
    main()

<commit_msg>fix method call<commit_after>import time
import grovepi
import atexit
import json
import sys
import logging

import argparse

from datetime import datetime

# get import working from a directory
from sensorvalue import SensorValue
from sensorconfig import SensorConfig
import notifier

from config import settings

def main():

    # two collections that really matter
    #one is the list of sensors that are supported by this code.
    supportedsensors = ['loudness', 'airquality', 'gas', 'tempandhumidity']

    sensorconfig = SensorConfig(settings)

    #two is the list of sensors configured in the settings.yaml file

    if not sensorconfig.isconfigvalid(supportedsensors):
        print 'Configuration is invalid'
        return

    sensordatafile = getsensorfilename()

    parser = argparse.ArgumentParser(description='Use this to poll sensor data from raspberry pi and the grove pi')
    parser.add_argument(
        '-p', '--poll', help='Poll all sensors in the config file at the configured interval', action='store_true')

    parser.add_argument('-s', '--sensortest', help='Name of the sensor to test. Supported sensors: ' + str(supportedsensors), default='nosensor')

    parser.add_argument('-m', '--mock', help='Do a mock sensor test', action='store_true')
    parser.add_argument('-n', '--notify', help='Perform a notification test', action='store_true')

    args = vars(parser.parse_args())

    parser.print_usage()

    mockingmode = False
    if args['mock']:
        mockingmode = True

    # if args['notify']:
    #     notifier.sendnotification("Test message",  "Test subject")

    if args['poll']:
            startautopolling(sensorconfig.configuredsensors, mockingmode, sensorconfig)

    if args['sensortest'] in supportedsensors:
        sensordata = getsensordata(args['sensortest'], mockingmode, sensorconfig)

        if sensordata != None:
            for data in sensordata:
                if data == None:
                    print 'No data was returned by the sensor'
                else:
                    print data.yaml()

    if args['sensortest'] in ['nosensor'] and args['sensortest'] not in supportedsensors:
        print 'the sensor ' +  args['sensortest'] + ' is not supported'
        print 'currently using a dictionary called supportedsensors at the top of this file to manage this list'
        print 'supported sensors: ' + str(supportedsensors)

    # The all case loops through all of the configured sensors and prints out there values
    if args['sensortest'] == "all":
        print "Looping through the sensors " + str(sensorconfig.configuredsensors)
        for item in sensorconfig.configuredsensors:
            data = getsensordata(item, mockingmode, sensorconfig)

            if data == None:
                print "No Data was returned"
                print "Exiting...."
                return

            for item in data:
                print item.yaml()

def getsensorconfig(sensorname):
    if sensorname in settings.keys():
        print sensorname + " is configured for port " + str(settings[sensorname]["port"])

        return settings[sensorname]["port"]
    else:
        print "missing config value for " + sensorname
        return

def getsensordata(sensorname, enablemocking, sensorconfig):

    if enablemocking:
        return

    try:

        if sensorname == "loudness":
            return getloudnessinfo(sensorname)
        if sensorname == "airquality":
            return getairqualitysensorvalue(sensorname)
        if sensorname == "gas":
            return getgassensorvalue(sensorname)
        if sensorname == "tempandhumidity":
            return gettempandhumidity(sensorname)
        if sensorname == "dust":
            return readdustsensor(sensorname)

    except:
        print sys.exc_info()[0]

def startautopolling(configuredsensors, enablemocking, sensorconfig):

    print "Starting to Autopoll the sensors"
    pollinginterval = settings["core"]["pollinginterval"]
    sensordatafile = getsensorfilename()

    #start the polling loop
    while True:
        if pollinginterval != settings["core"]["pollinginterval"]:
            print "polling interval changed from " + str(pollinginterval) + " to " + settings["core"]["pollinginterval"]
            pollinginterval = settings["core"]["pollinginterval"]

        #check for a new polling interval
        values = []

        for item in configuredsensors:
            sensorvalue = getsensordata(item, enablemocking, sensorconfig)
            if sensorvalue != None:
                values.append(sensorvalue)

        writetofile(values, sensordatafile)

        time.sleep(pollinginterval)

        # getairqualitysensorvalue()
        # getgassensorvalue(location, gas_sensor_pin)
        # https://github.com/DexterInd/GrovePi/blob/master/Software/Python/grove_gas_sensor.py

def writetofile(data, sensordatafile):
    with open(sensordatafile, 'ab') as f:
        for items in data:
            for item in items:
                f.write(item.writecsv() + '\n')

def getsensorfilename():
    return "sensorlog" + datetime.now().strftime('%Y%m%d%H%M%S') + ".log"

def readdustsensor(sensorname):

    sensordata = []

    pin = getsensorconfig(sensorname)

    atexit.register(grovepi.dust_sensor_dis)

    print("Reading from the dust sensor")
    grovepi.dust_sensor_en()

    try:
                [new_val,lowpulseoccupancy] = grovepi.dustSensorRead()

                print "new_val: " + str(new_val)
                print "lowpulseoccupancy: " + str(lowpulseoccupancy)

                if new_val:
                    print(lowpulseoccupancy)
                    sensordata.append(SensorValue(lowpulseoccupancy, 'none', 'Dust', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def gettempandhumidity(sensorname):

    pin = getsensorconfig(sensorname)
    dht_sensor_type = 0             # change this depending on your sensor type - see header comment

    try:
        [temp,humidity] = grovepi.dht(pin,dht_sensor_type)
        print "temp =", temp, " humidity =", humidity

        sensordata = []
        sensordata.append(SensorValue(temp, 'none', 'temp', 'location'))
        sensordata.append(SensorValue(humidity, 'none', 'humidity', 'location'))

    except IOError:
        print "Error"
    return sensordata

def getloudnessinfo(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)
    try:
        # Read the sound level
        sensor_value = grovepi.analogRead(pin)
        sensordata.append(SensorValue(sensor_value, 'none', 'Loudness', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def getgassensorvalue(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)

    grovepi.pinMode(pin,"INPUT")
    try:
        # Get sensor value
        sensor_value = grovepi.analogRead(pin)

        # Calculate gas density - large value means more dense gas
        density = (float)(sensor_value / 1024)
        sensordata.append(SensorValue(sensor_value, 'none', 'Gas', 'location'))

    except IOError:
        print ("Error")

    return sensordata

def getairqualitysensorvalue(sensorname):

    sensordata = []
    pin = getsensorconfig(sensorname)

    grovepi.pinMode(pin,"INPUT")

    try:
        # Get sensor value
        sensor_value = grovepi.analogRead(pin)

        if sensor_value > 700:
            print ("High pollution")
        elif sensor_value > 300:
            print ("Low pollution")
        else:
            print ("Air fresh")
        sensordata.append(SensorValue(sensor_value, 'none', 'airquality', 'location'))
    except IOError:
        print ("Error")

    return sensordata

if __name__ == '__main__':
    main()

<|endoftext|>


<commit_before>#-*- coding: utf-8 -*-
#!/usr/bin/env python
import serial
import argparse
import struct
import os.path
import time

# Table 3. ASCII commands supported by SC18IM700
# ASCII command Hex value Command function
# [X] S 0x53 I2C-bus START
# [X] P 0x50 I2C-bus STOP
# [_] R 0x52 read SC18IM700 internal register
# [_] W 0x57 write to SC18IM700 internal register
# [_] I 0x49 read GPIO port
# [_] O 0x4F write to GPIO port
# [_] Z 0x5A power down
# [X] C 0x43 change channel

## RS232C to I2C converter using mbed
class serial2i2c(object):
    """
    serial2i2c: RS232C to I2C converter using mbed
    "C| '0'| P"
    "C| '1'| P"
    "C| '2'| P"
    "C| '3'| P"
    "S| 0x_8 _0| 0x_0 _4| 0x_D _E _A _D _B _E _A _F| P"
    "S| 0x_8 _0| 0x_0 _4| 0x_D _E _A _D _B _E _A _F| S| 0x_8 _1| 0x_0 _4| P"
    "S| 0x_8 _1| 0x_0 _4| P"
    "R| '0'| P"
    "R| '0'| '1'| ...| P"
    "W| '0' 0x_a _a| P"
    "W| '0' 0x_a _a| '1' 0x_b _b| ...| P"
    "I| P"
    "O| 0x_a _a| P"
    """
    _ser = 0
    _channel = 0
    _wait = 1e-5

    ## constructor
    # @param port COM port which device is conected
    # @param baud baudrate
    def __init__(self, port = 'com1', baud = '115200'):
        try:
            self._ser = serial.Serial(port, baudrate = baud, timeout = 1)
        except:
            raise

    ## sets channel by sending "C" command packet
    # @param channel I2C bus channel
    # @return response from module
    def setChannel(self, channel = 0):
        self._channel = channel
        self.raw_write("C" + str(self._channel) + "P")
        time.sleep(self._wait)
        return self.raw_read()

    ## reads multi byte data
    # @param address 8bit I2C slave address in HEX
    # @param length bytes to read
    # @return response string from device
    def read(self, address, length = 1):
        packet = ['S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        packet.insert(1, chr(ord(address[0]) | 1))
        packet.insert(1, address[1])

        for _l in self._hex2ascii(length, 0xd0):
            packet.insert(3, _l)

#        for _p in packet:
#            self._ser.write(_p)
        self.raw_write("".join(packet))

        time.sleep(self._wait * length * 2)
        return self.raw_read()

    ## writes multi byte data
    # @param address 8bit I2C slave address in HEX
    # @param data data to send
    # @return response string from device
    def write(self, address, data = 0):
        packet = ['S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        for _a in address:
            packet.insert(1, _a)

        data = self._hex2ascii(data, 0xb0)
        length = len(data) / 2

        for _l in self._hex2ascii(length,0xc0):
            packet.insert(3, _l)

        for _d in data:
            packet.insert(5, _d)

#        for _p in packet:
#            self._ser.write(_p)
        self.raw_write("".join(packet))

        time.sleep(self._wait * length * 2)
        return self.raw_read()

    ## writes data and then reads from same slave device
    # @param address I2C slave address in HEX
    # @param wdata data to send in HEX
    # @param rlength bytes to read
    # @return response string from device
    def write_and_read(self, address, wdata = 0, rlength = 1):
        packet = ['S', 'S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        for _a in address:
            packet.insert(1, _a)

        wdata = self._hex2ascii(wdata, 0xb0)
        wlength = len(wdata) / 2

        for _wl in self._hex2ascii(wlength, 0xc0):
            packet.insert(3, _wl)

        for _wd in wdata:
            packet.insert(5, _wd)

        packet.insert(6 + wlength * 2, chr(ord(address[0]) | 1))
        packet.insert(6 + wlength * 2, address[1])

        for _rl in self._hex2ascii(rlength, 0xd0):
            packet.insert(8 + wlength * 2, _rl)

        self.raw_write("".join(packet))

        time.sleep(self._wait * rlength * 2)
        return self.raw_read()

    ## sends raw data on serial port
    def raw_write(self, data="DEADBEAF"):
        self._ser.write(data)

    ## reads raw data from serial port
    def raw_read(self):
        return (self._ser.readline().strip())

    ## sends 'S' command packet to make start condition
    def start(self):
        self._ser.write("S")

    ## sends 'P' command packet to make stop condition
    def stop(self):
        self._ser.write("P")
        time.sleep(self._wait)

    ## reads data from device's own register
    # @param registers register addresses
    # @return response string from device
    def reg_read(self, registers = "012"):
        packet = ['R', 'P']

        packet.insert(1, registers)

        self.raw_write("".join(packet))
        return self.raw_read()

    ## writes data into device's own register
    # @param register list of number and data list
    # @return response string from device
    def reg_write(self, pair = [ ['1', 0xFF], ]):
        packet = ['W', 'P']

        for _p in pair:
            reg, data = _p
            data = self._hex2ascii(data, 0xA0)
            data.reverse()

            packet.insert(1, reg)
            packet.insert(2, "".join(data))

        self.raw_write("".join(packet))

        return self.raw_read()

    ## converts hex data to string
    # @param h data in HEX
    # @param mask mask data in HEX, LSB must be 0, MSB must not be 0 (0x?0, ?>0)
    # @return converted format in list
    def _hex2ascii(self, h, mask = 0xa0):
        chars_in_reverse = []
        chars_in_reverse.append(chr(mask | (h & 0x0F)))
        chars_in_reverse.append(chr(mask | ((h >> 4) & 0x0F)))
        h = h >> 8
        while h != 0x0:
            chars_in_reverse.append(chr(mask | (h & 0x0F)))
            chars_in_reverse.append(chr(mask | ((h >> 4) & 0x0F)))
            h = h >> 8

        return (chars_in_reverse)

if __name__=="__main__":
    class MyParser(object):
        def __init__(self):
            self._parser = argparse.ArgumentParser(description="hogeeee")
            self._parser.add_argument('--port','-p', help='number or name of serial port', default='com1')
    #        self._parser.add_argument('--port','-p', help='number or name of serial port', default='/dev/ttyACM0')
    #        self._parser.add_argument('--mon','-m', help='number or name of serial port', default='/dev/ttyACM0')
            self._parser.add_argument('--baud','-b', help='baudrate of serial port', default='115200')#460800
            self.args=self._parser.parse_args(namespace=self)

#    parser.print_help()
    parser = MyParser()
#    args=parser.parse_args()
#    print args
#    print args.port, args.baud

    port = parser.args.port # port number, different in OSes
    baud = parser.args.baud
    dev = serial2i2c(port, baud)
##    channel="C0P"
##    i2cw="S"+chr(0x80)+chr(0x04)+struct.pack(">4B",0xde,0xad,0xbe,0xaf)+"P"
##    i2crw="S"+chr(0x80)+chr(0x04)+struct.pack(">4B",0xde,0xad,0xbe,0xaf)+"S"+chr(0x81)+chr(0x04)+"P"
#    print channel,i2cw

#    raw_input("wait, press enter to set channel 0")
    raw_input("wait, press enter to transferring data")
    print dev.setChannel(0)
    if False:
        for hoge in range(0x050, 0x300, 0x10):
            print "%03X," %(hoge),
            print dev.write_and_read(0xFE&(0xD0|hoge>>7), hoge, 16)

###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(1)
###    print dev.write_and_read(0xD0,0xD0,16)
###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(2)
###    print dev.write_and_read(0xD0,0xD0,16)
###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(3)
###    print dev.write_and_read(0xD0,0xD0,16)

# 0x141,0x00
# 0x142,0xd2
# 0x142,0xb0
# 0x142,0xa9
# 0x142,0x8a
# 0x142,0xa7
# 0x142,0xa8
# 0x142,0xb1
##    print dev.write(0xD2,0x4100)
##    print dev.write(0xD2,0x42d2)
##    print dev.write(0xD2,0x42b0)
##    print dev.write(0xD2,0x42a9)
##    print dev.write(0xD2,0x428a)
##    print dev.write(0xD2,0x42a7)
##    print dev.write(0xD2,0x42a8)
##    print dev.write(0xD2,0x42b1)
##    time.sleep(0.1)
##    print dev.write(0xD2,0x4701)
##    time.sleep(0.1)
##    print dev.write_and_read(0xD0,0x50,16)
##    print dev.write_and_read(0xD0,0xD0,16)
#    print dev.write_and_read(0xD0,0x5D00,16)
##    print dev.write(0xD0,0x5D01)
##    time.sleep(0.1)
##    print dev.write(0xD0,0xD800)
##    print dev.write(0xD0,0xD846)
##    print dev.write(0xD0,0x5D00)

#    print dev.read(0xD0,1)
    print dev.reg_read('012')
    print dev.reg_write([ ['2',0xFF],['0',0xFF] ])
    dev.raw_write('IP')
    print dev.raw_read()
    try:
        while True:
            for hoge in range(0,256):
                foo=dev._hex2ascii(hoge)
                foo.reverse()
                dev.raw_write('O'+"".join(foo)+'P')
                print dev.raw_read()
    except:
        print dev.raw_read()
    print dev.reg_read('012')
    dev.raw_write('IP')
    print dev.raw_read()
    while False:
        print dev.write(0xD0, 0x5D00)
##        print dev.write(0xD0,0x5D01)
#        print dev.write_and_read(0xD0,0x50,16)
#        print dev.write_and_read(0xD0,0xD0,16)
        #print dev.write_and_read(0xD2,0x10,15)
#        print dev.write_and_read(0xD0,0x50,16)
#        print dev.write_and_read(0xD4,0x10,16)
##    print "%02X"%(int(dev.write_and_read(0x90,0xdeadbeaf,50).split(',')[0],16))
#    print dev.ser.readline().strip()

##    raw_input("wait, press enter to send repeated start command")
##    dev.ser.write(i2crw)
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'R' command")
##    dev.ser.write('RP')
##    print dev.ser.readline()
##    neroaddr=0xD0
##    nerodata=[
##        [0xD8,0x00],
##        [0xD8,0x46],
##        [0xD8,0x7F],
##    ]
##    nerodata2=""
##    for hoge in nerodata:
##        print dev._hex2ascii(hoge),
##
###    print dev._hex2ascii(nerodata)
##
##    print dev.write(neroaddr,nerodata)

##    raw_input("wait, press enter to send 'W' command")
##    ser.write('WP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'I' command")
##    ser.write('IP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'O' command")
##    ser.write('OP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'Z' command")
##    ser.write('ZP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send unknown command")
##    ser.write('XP')
##    print dev.ser.readline()

#    while(ser.inWaiting()>0):
#        print ser.readline()
#    dev.ser.close()
<commit_msg>I, O commands test code fix<commit_after>#-*- coding: utf-8 -*-
#!/usr/bin/env python
import serial
import argparse
import struct
import os.path
import time

# Table 3. ASCII commands supported by SC18IM700
# ASCII command Hex value Command function
# [X] S 0x53 I2C-bus START
# [X] P 0x50 I2C-bus STOP
# [_] R 0x52 read SC18IM700 internal register
# [_] W 0x57 write to SC18IM700 internal register
# [_] I 0x49 read GPIO port
# [_] O 0x4F write to GPIO port
# [_] Z 0x5A power down
# [X] C 0x43 change channel

## RS232C to I2C converter using mbed
class serial2i2c(object):
    """
    serial2i2c: RS232C to I2C converter using mbed
    "C| '0'| P"
    "C| '1'| P"
    "C| '2'| P"
    "C| '3'| P"
    "S| 0x_8 _0| 0x_0 _4| 0x_D _E _A _D _B _E _A _F| P"
    "S| 0x_8 _0| 0x_0 _4| 0x_D _E _A _D _B _E _A _F| S| 0x_8 _1| 0x_0 _4| P"
    "S| 0x_8 _1| 0x_0 _4| P"
    "R| '0'| P"
    "R| '0'| '1'| ...| P"
    "W| '0' 0x_a _a| P"
    "W| '0' 0x_a _a| '1' 0x_b _b| ...| P"
    "I| '0'| P"
    "O| '0'| 0x_a _a| P"
    """
    _ser = 0
    _channel = 0
    _wait = 1e-3
    CHIP_ID = '0'
    GPIO0_STAT = '1'
    GPIO1_STAT = '2'
    GPIO0_CONF = '3'
    GPIO1_CONF = '4'

    ## constructor
    # @param port COM port which device is conected
    # @param baud baudrate
    def __init__(self, port = 'com1', baud = '115200'):
        try:
            self._ser = serial.Serial(port, baudrate = baud, timeout = 1)
        except:
            raise

    ## sets channel by sending "C" command packet
    # @param channel I2C bus channel
    # @return response from module
    def setChannel(self, channel = 0):
        self._channel = channel
        self.raw_write("C" + str(self._channel) + "P")
        time.sleep(self._wait)
        return self.raw_read()

    ## reads multi byte data
    # @param address 8bit I2C slave address in HEX
    # @param length bytes to read
    # @return response string from device
    def read(self, address, length = 1):
        packet = ['S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        packet.insert(1, chr(ord(address[0]) | 1))
        packet.insert(1, address[1])

        for _l in self._hex2ascii(length, 0xd0):
            packet.insert(3, _l)

#        for _p in packet:
#            self._ser.write(_p)
        self.raw_write("".join(packet))

        time.sleep(self._wait * length * 2)
        return self.raw_read()

    ## writes multi byte data
    # @param address 8bit I2C slave address in HEX
    # @param data data to send
    # @return response string from device
    def write(self, address, data = 0):
        packet = ['S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        for _a in address:
            packet.insert(1, _a)

        data = self._hex2ascii(data, 0xb0)
        length = len(data) / 2

        for _l in self._hex2ascii(length,0xc0):
            packet.insert(3, _l)

        for _d in data:
            packet.insert(5, _d)

#        for _p in packet:
#            self._ser.write(_p)
        self.raw_write("".join(packet))

        time.sleep(self._wait * length * 2)
        return self.raw_read()

    ## writes data and then reads from same slave device
    # @param address I2C slave address in HEX
    # @param wdata data to send in HEX
    # @param rlength bytes to read
    # @return response string from device
    def write_and_read(self, address, wdata = 0, rlength = 1):
        packet = ['S', 'S', 'P']

        address = self._hex2ascii(address, 0xa0)
        alength = len(address) / 2
        for _a in address:
            packet.insert(1, _a)

        wdata = self._hex2ascii(wdata, 0xb0)
        wlength = len(wdata) / 2

        for _wl in self._hex2ascii(wlength, 0xc0):
            packet.insert(3, _wl)

        for _wd in wdata:
            packet.insert(5, _wd)

        packet.insert(6 + wlength * 2, chr(ord(address[0]) | 1))
        packet.insert(6 + wlength * 2, address[1])

        for _rl in self._hex2ascii(rlength, 0xd0):
            packet.insert(8 + wlength * 2, _rl)

        self.raw_write("".join(packet))

        time.sleep(self._wait * rlength * 2)
        return self.raw_read()

    ## sends raw data on serial port
    def raw_write(self, data="DEADBEAF"):
        self._ser.write(data)

    ## reads raw data from serial port
    def raw_read(self):
        return (self._ser.readline().strip())

    ## sends 'S' command packet to make start condition
    def start(self):
        self._ser.write("S")

    ## sends 'P' command packet to make stop condition
    def stop(self):
        self._ser.write("P")
        time.sleep(self._wait)

    ## reads data from device's own register
    # @param registers register addresses
    # @return response string from device
    def reg_read(self, registers = "012"):
        packet = ['R', 'P']

        packet.insert(1, registers)

        self.raw_write("".join(packet))
        return self.raw_read()

    ## writes data into device's own register
    # @param register list of number and data list
    # @return response string from device
    def reg_write(self, pair = [ ['1', 0xFF], ]):
        packet = ['W', 'P']

        for _p in pair:
            reg, data = _p
            data = self._hex2ascii(data, 0xA0)
            data.reverse()

            packet.insert(1, reg)
            packet.insert(2, "".join(data))

        length=len(packet)
        self.raw_write("".join(packet))

        time.sleep(self._wait * length)

        return self.raw_read()

    ## converts hex data to string
    # @param h data in HEX
    # @param mask mask data in HEX, LSB must be 0, MSB must not be 0 (0x?0, ?>0)
    # @return converted format in list
    def _hex2ascii(self, h, mask = 0xa0):
        chars_in_reverse = []
        chars_in_reverse.append(chr(mask | (h & 0x0F)))
        chars_in_reverse.append(chr(mask | ((h >> 4) & 0x0F)))
        h = h >> 8
        while h != 0x0:
            chars_in_reverse.append(chr(mask | (h & 0x0F)))
            chars_in_reverse.append(chr(mask | ((h >> 4) & 0x0F)))
            h = h >> 8

        return (chars_in_reverse)

if __name__=="__main__":
    class MyParser(object):
        def __init__(self):
            self._parser = argparse.ArgumentParser(description="hogeeee")
            self._parser.add_argument('--port','-p', help='number or name of serial port', default='com1')
    #        self._parser.add_argument('--port','-p', help='number or name of serial port', default='/dev/ttyACM0')
    #        self._parser.add_argument('--mon','-m', help='number or name of serial port', default='/dev/ttyACM0')
            self._parser.add_argument('--baud','-b', help='baudrate of serial port', default='115200')#460800
            self.args=self._parser.parse_args(namespace=self)

#    parser.print_help()
    parser = MyParser()
#    args=parser.parse_args()
#    print args
#    print args.port, args.baud

    port = parser.args.port # port number, different in OSes
    baud = parser.args.baud
    dev = serial2i2c(port, baud)
##    channel="C0P"
##    i2cw="S"+chr(0x80)+chr(0x04)+struct.pack(">4B",0xde,0xad,0xbe,0xaf)+"P"
##    i2crw="S"+chr(0x80)+chr(0x04)+struct.pack(">4B",0xde,0xad,0xbe,0xaf)+"S"+chr(0x81)+chr(0x04)+"P"
#    print channel,i2cw

#    raw_input("wait, press enter to set channel 0")
    raw_input("wait, press enter to transferring data")
    print dev.setChannel(0)
    dev.write(0xD2,0x4100)
    dev.write(0xD2,0x42d2)
    dev.write(0xD2,0x42b0)
    dev.write(0xD2,0x42a9)
    dev.write(0xD2,0x428a)
    dev.write(0xD2,0x42a7)
    dev.write(0xD2,0x42a8)
    dev.write(0xD2,0x42b1)
    print dev.write(0xD2,0x4701)
    if False:
        for hoge in range(0x050, 0x300, 0x10):
            print "%03X," %(hoge),
            print dev.write_and_read((0xD0|((hoge&0x300)>>7)), hoge&0xFF, 16)

###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(1)
###    print dev.write_and_read(0xD0,0xD0,16)
###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(2)
###    print dev.write_and_read(0xD0,0xD0,16)
###    raw_input("wait, press enter to transferring data")
###    print dev.setChannel(3)
###    print dev.write_and_read(0xD0,0xD0,16)

# 0x141,0x00
# 0x142,0xd2
# 0x142,0xb0
# 0x142,0xa9
# 0x142,0x8a
# 0x142,0xa7
# 0x142,0xa8
# 0x142,0xb1
##    print dev.write(0xD2,0x4100)
##    print dev.write(0xD2,0x42d2)
##    print dev.write(0xD2,0x42b0)
##    print dev.write(0xD2,0x42a9)
##    print dev.write(0xD2,0x428a)
##    print dev.write(0xD2,0x42a7)
##    print dev.write(0xD2,0x42a8)
##    print dev.write(0xD2,0x42b1)
##    time.sleep(0.1)
##    print dev.write(0xD2,0x4701)
##    time.sleep(0.1)
##    print dev.write_and_read(0xD0,0x50,16)
##    print dev.write_and_read(0xD0,0xD0,16)
#    print dev.write_and_read(0xD0,0x5D00,16)
##    print dev.write(0xD0,0x5D01)
##    time.sleep(0.1)
##    print dev.write(0xD0,0xD800)
##    print dev.write(0xD0,0xD846)
##    print dev.write(0xD0,0x5D00)

#    print dev.read(0xD0,1)
    print dev.reg_read('01234')
    print dev.reg_write([ [dev.GPIO0_STAT,0xFF],[dev.GPIO0_CONF,0xFF] ])
    dev.raw_write('I01234P')
    print dev.raw_read()
    try:
        while True:
            for hoge in range(0,256):
                print dev.reg_write([[dev.GPIO0_STAT,hoge]])
    except:
        print dev.raw_read()
        print dev.reg_write([[dev.GPIO0_STAT,0x00]])

    print "reg_read = "+dev.reg_read('01234')
    dev.raw_write('I'+dev.GPIO0_STAT+'P')
    print "port_read = "+ dev.raw_read()
    while False:
        print dev.write(0xD0, 0x5D00)
##        print dev.write(0xD0,0x5D01)
#        print dev.write_and_read(0xD0,0x50,16)
#        print dev.write_and_read(0xD0,0xD0,16)
        #print dev.write_and_read(0xD2,0x10,15)
#        print dev.write_and_read(0xD0,0x50,16)
#        print dev.write_and_read(0xD4,0x10,16)
##    print "%02X"%(int(dev.write_and_read(0x90,0xdeadbeaf,50).split(',')[0],16))
#    print dev.ser.readline().strip()

##    raw_input("wait, press enter to send repeated start command")
##    dev.ser.write(i2crw)
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'R' command")
##    dev.ser.write('RP')
##    print dev.ser.readline()
##    neroaddr=0xD0
##    nerodata=[
##        [0xD8,0x00],
##        [0xD8,0x46],
##        [0xD8,0x7F],
##    ]
##    nerodata2=""
##    for hoge in nerodata:
##        print dev._hex2ascii(hoge),
##
###    print dev._hex2ascii(nerodata)
##
##    print dev.write(neroaddr,nerodata)

##    raw_input("wait, press enter to send 'W' command")
##    ser.write('WP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'I' command")
##    ser.write('IP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'O' command")
##    ser.write('OP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send 'Z' command")
##    ser.write('ZP')
##    print dev.ser.readline()

##    raw_input("wait, press enter to send unknown command")
##    ser.write('XP')
##    print dev.ser.readline()

#    while(ser.inWaiting()>0):
#        print ser.readline()
#    dev.ser.close()
<|endoftext|>


<commit_before># ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals
def execute():
	import webnotes
	from stock.stock_ledger import update_entries_after

	res = webnotes.conn.sql("""select distinct item_code, warehouse from `tabStock Ledger Entry`
		where posting_time = '00:00'""")

	i=0
	for d in res:
	    try:
	        update_entries_after({ "item_code": d[0], "warehouse": d[1]	})
	    except:
	        pass
	    i += 1
	    if i%50 == 0:
	        webnotes.conn.sql("commit")
	        webnotes.conn.sql("start transaction")<commit_msg>[fixes] repost stock: commit after every 20<commit_after># ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals
def execute():
	import webnotes
	from stock.stock_ledger import update_entries_after

	res = webnotes.conn.sql("""select distinct item_code, warehouse from `tabStock Ledger Entry`
		where posting_time = '00:00'""")

	i=0
	for d in res:
	    try:
	        update_entries_after({ "item_code": d[0], "warehouse": d[1]	})
	    except:
	        pass
	    i += 1
	    if i%20 == 0:
	        webnotes.conn.sql("commit")
	        webnotes.conn.sql("start transaction")<|endoftext|>