<commit_before>import sys
import re
import os.path
from io import BytesIO
from gzip import GzipFile
import mimetypes
import hashlib
from base64 import urlsafe_b64encode as b64encode

# Python 2/3 imports
if sys.version_info[0] < 3:
    import urllib as urlparse
else:
    import urllib.parse as urlparse

class MissingAsset(Exception):
    pass

class Asset(object):
    """
    An object representing a static asset.

    """
    processed = False
    _content = None
    _encoded = None

    def __init__(self, path):
        self.path = path
        self.headers = {
            'Cache-Control': 'max-age=31556926',
        }
        mtype, encoding = mimetypes.guess_type(path)
        if mtype is not None:
            self.headers['Content-Type'] = mtype

    def process(self, manifest):
        """
        Do any processing necessary to prepare the file for upload.

        """
        self.processed = True

    def encode(self):
        """
        Encode the content.  (Compression, mainly.)

        """
        return self.content

    @property
    def content(self):
        if self._content is not None:
            return self._content
        with open(self.path, 'rb') as fh:
            self._content = fh.read()
        return self._content

    @content.setter
    def content(self, value):
        self._content = value

    @property
    def encoded(self):
        if self._encoded is None:
            self._encoded = self.encode()
        return self._encoded

    @property
    def filename(self):
        hash = hashlib.sha1(self.content).digest()
        return b64encode(hash).decode('ascii').rstrip('=')

class CompressedAsset(Asset):
    #: Compressable mimetypes, exclude text/* types (which are assumed)
    COMPRESSABLE = {
        'image/svg+xml',
        'application/javascript',
        'application/json',
        'application/xml',
        'application/xhtml+xml',
    }

    def encode(self):
        encoded = super(CompressedAsset, self).encode()
        io = BytesIO()
        with GzipFile(fileobj=io, mode='wb') as gz:
            gz.write(encoded)
        self.headers['Content-Encoding'] = 'gzip'
        return io.getvalue()

class StylesheetAsset(CompressedAsset):
    URL_REGEX = re.compile(r'url\([\'"]?([^\'"\)]*)[\'"]?\)', re.I)

    def process(self, manifest):
        if self.processed:
            return

        def sub_urls(match):
            url = match.group(1)
            if url.startswith('http://') or url.startswith('https://'):
                return 'url("{}")'.format(url)
            path = os.path.normpath(
                os.path.join(
                    os.path.dirname(self.path),
                    urlparse.unquote(url),
                )
            )
            try:
                asset = manifest[path]
                asset.process(manifest)
                # (We know the asset filename is URL safe, no need to quote
                return 'url("{}")'.format(asset.filename)
            except KeyError:
                raise MissingAsset('Could not find "{}" in "{}"'.format(
                    url, self.path,
                ))

        self.content = self.URL_REGEX.sub(
            sub_urls, self.content.decode('ascii')
        ).encode('ascii')

        super(StylesheetAsset, self).process(manifest)

def create_asset_from_path(path):
    """
    Given a filepath, create an appropriate asset object.

    :param path:  The file path.
    :type path:  str

    :returns:  The appropriate asset.
    :rtype:  :class:`Asset`

    """
    mtype, _ = mimetypes.guess_type(path)
    if mtype == 'text/css':
        return StylesheetAsset(path)
    elif mtype.startswith('text/') or mtype in CompressedAsset.COMPRESSABLE:
        return CompressedAsset(path)
    else:
        return Asset(path)
<commit_msg>Fix issue with unknown mimetype in `create_asset_from_path`<commit_after>import sys
import re
import os.path
from io import BytesIO
from gzip import GzipFile
import mimetypes
import hashlib
from base64 import urlsafe_b64encode as b64encode

# Python 2/3 imports
if sys.version_info[0] < 3:
    import urllib as urlparse
else:
    import urllib.parse as urlparse

class MissingAsset(Exception):
    pass

class Asset(object):
    """
    An object representing a static asset.

    """
    processed = False
    _content = None
    _encoded = None

    def __init__(self, path):
        self.path = path
        self.headers = {
            'Cache-Control': 'max-age=31556926',
        }
        mtype, encoding = mimetypes.guess_type(path)
        if mtype is not None:
            self.headers['Content-Type'] = mtype

    def process(self, manifest):
        """
        Do any processing necessary to prepare the file for upload.

        """
        self.processed = True

    def encode(self):
        """
        Encode the content.  (Compression, mainly.)

        """
        return self.content

    @property
    def content(self):
        if self._content is not None:
            return self._content
        with open(self.path, 'rb') as fh:
            self._content = fh.read()
        return self._content

    @content.setter
    def content(self, value):
        self._content = value

    @property
    def encoded(self):
        if self._encoded is None:
            self._encoded = self.encode()
        return self._encoded

    @property
    def filename(self):
        hash = hashlib.sha1(self.content).digest()
        return b64encode(hash).decode('ascii').rstrip('=')

class CompressedAsset(Asset):
    #: Compressable mimetypes, exclude text/* types (which are assumed)
    COMPRESSABLE = {
        'image/svg+xml',
        'application/javascript',
        'application/json',
        'application/xml',
        'application/xhtml+xml',
    }

    def encode(self):
        encoded = super(CompressedAsset, self).encode()
        io = BytesIO()
        with GzipFile(fileobj=io, mode='wb') as gz:
            gz.write(encoded)
        self.headers['Content-Encoding'] = 'gzip'
        return io.getvalue()

class StylesheetAsset(CompressedAsset):
    URL_REGEX = re.compile(r'url\([\'"]?([^\'"\)]*)[\'"]?\)', re.I)

    def process(self, manifest):
        if self.processed:
            return

        def sub_urls(match):
            url = match.group(1)
            if url.startswith('http://') or url.startswith('https://'):
                return 'url("{}")'.format(url)
            path = os.path.normpath(
                os.path.join(
                    os.path.dirname(self.path),
                    urlparse.unquote(url),
                )
            )
            try:
                asset = manifest[path]
                asset.process(manifest)
                # (We know the asset filename is URL safe, no need to quote
                return 'url("{}")'.format(asset.filename)
            except KeyError:
                raise MissingAsset('Could not find "{}" in "{}"'.format(
                    url, self.path,
                ))

        self.content = self.URL_REGEX.sub(
            sub_urls, self.content.decode('ascii')
        ).encode('ascii')

        super(StylesheetAsset, self).process(manifest)

def create_asset_from_path(path):
    """
    Given a filepath, create an appropriate asset object.

    :param path:  The file path.
    :type path:  str

    :returns:  The appropriate asset.
    :rtype:  :class:`Asset`

    """
    mtype, _ = mimetypes.guess_type(path)
    if mtype is None:
        return Asset(path)
    elif mtype == 'text/css':
        return StylesheetAsset(path)
    elif mtype.startswith('text/') or mtype in CompressedAsset.COMPRESSABLE:
        return CompressedAsset(path)
    else:
        return Asset(path)
<|endoftext|>


<commit_before># Copyright 2016 Pinterest, Inc.
#
# 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.

"""
Django settings for deploy_board project.

For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import logging

logger = logging.getLogger(__name__)

BASE_DIR = os.path.dirname(__file__)

PROJECT_PATH = BASE_DIR

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
)

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("SECRET_KEY", None)
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
# OAuth
OAUTH_ENABLED_STR = os.getenv("OAUTH_ENABLED", "OFF")
if OAUTH_ENABLED_STR == "OFF":
    OAUTH_ENABLED = False
else:
    OAUTH_ENABLED = True
    OAUTH_CLIENT_ID = os.getenv("OAUTH_CLIENT_ID")
    OAUTH_CLIENT_SECRET = os.getenv("OAUTH_CLIENT_SECRET")
    OAUTH_CALLBACK = os.getenv("OAUTH_CALLBACK")
    OAUTH_DOMAIN = os.getenv("OAUTH_DOMAIN")
    OAUTH_CLIENT_TYPE = os.getenv("OAUTH_CLIENT_TYPE")
    OAUTH_USER_INFO_URI = os.getenv("OAUTH_USER_INFO_URI")
    OAUTH_USER_INFO_KEY = os.getenv("OAUTH_USER_INFO_KEY")
    OAUTH_ACCESS_TOKEN_URL = os.getenv("OAUTH_ACCESS_TOKEN_URL")
    OAUTH_AUTHORIZE_URL = os.getenv("OAUTH_AUTHORIZE_URL")
    OAUTH_DEFAULT_SCOPE = os.getenv("OAUTH_DEFAULT_SCOPE")
    OAUTH_USERNAME_INFO_KEY = os.getenv("OAUTH_USERNAME_INFO_KEY")
    OAUTH_EXTRACT_USERNAME_FROM_EMAIL = os.getenv("OAUTH_EXTRACT_USERNAME_FROM_EMAIL")

# Teletraan backend service url
TELETRAAN_SERVICE_URL = os.getenv("TELETRAAN_SERVICE_URL")
TELETRAAN_SERVICE_VERSION = os.getenv("TELETRAAN_SERVICE_VERSION")
TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN = os.getenv("TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN", None)
TELETRAAN_HOST_INFORMATION_URL = os.getenv("HOST_INFORMATION_URL")

# CMDB vars
CMDB_API_HOST = os.getenv("CMDB_API_HOST", "http://localhost:8080/")
CMDB_INSTANCE_URL = os.getenv("CMDB_INSTANCE_URL", "api/cmdb/getinstance/")
CMDB_UI_HOST = os.getenv("CMDB_UI_HOST", "localhost")
PHOBOS_URL = os.getenv("PHOBOS_URL")

# Serviceframework add-on vars
SERVICE_RATELIMIT_CONFIG_URL = os.getenv("SERVICE_RATELIMIT_CONFIG_URL")
STATSBOARD_API_FORMAT = os.getenv("STATSBOARD_API_FORMAT", "OFF")
RATELIMIT_ENABLED_METRIC_FORMAT = os.getenv("RATELIMIT_ENABLED_METRIC_FORMAT", "OFF")
ENABLING_SERVICE_RATELIMIT_URL = os.getenv("ENABLING_SERVICE_RATELIMIT_URL", "OFF")
KAFKA_MSGS_DELIVERED_METRIC = os.getenv("KAFKA_MSGS_DELIVERED_METRIC", "OFF")
DASHBOARD_URL_ENDPOINT_FORMAT = os.getenv("DASHBOARD_URL_ENDPOINT_FORMAT","OFF")

# For rolling out new features
GUINEA_PIG_ENVS = os.getenv("GUINEA_PIG_ENVS", "").split(",")
KAFKA_LOGGING_ADD_ON_ENVS = os.getenv("KAFKA_LOGGING_ADD_ON_ENVS", "").split(",")

LOG_DIR = os.getenv("LOG_DIR")
LOG_LEVEL = os.getenv("LOG_LEVEL")

# Change to your domain or hosts
if LOG_LEVEL == 'DEBUG':
    DEBUG = True
    TEMPLATE_DEBUG = True
    ALLOWED_HOSTS = []
else:
    ALLOWED_HOSTS = ['*']

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level': LOG_LEVEL,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': '%s/service.log' % LOG_DIR,
            'maxBytes': 1024 * 1024 * 5,  # 5 MB
            'backupCount': 5,
            'formatter': 'standard',
        },
        'request_handler': {
            'level': LOG_LEVEL,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': '%s/access.log' % LOG_DIR,
            'maxBytes': 1024 * 1024 * 5,  # 5 MB
            'backupCount': 5,
            'formatter': 'standard',
        },
        'console': {
            'level': LOG_LEVEL,
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default', 'console'],
            'level': LOG_LEVEL,
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': LOG_LEVEL,
            'propagate': False
        },
    }
}

# Application definition
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'deploy_board.webapp',
)

oauth_middleware = 'deploy_board.webapp.security.DelegatedOAuthMiddleware'
if TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN:
    oauth_middleware = 'deploy_board.webapp.security.FixedOAuthMiddleware'

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    oauth_middleware,
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'deploy_board.webapp.error_views.ExceptionHandlerMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.static",
    "django.contrib.messages.context_processors.messages",
    "django.core.context_processors.request",
)

ROOT_URLCONF = 'deploy_board.urls'

WSGI_APPLICATION = 'deploy_board.wsgi.application'

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# The number of days since the build publish date required to trigger an old build version warning message
OLD_BUILD_WARNING_THRESHOLD_DAYS = 10

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(PROJECT_PATH, "static"),
)
#STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

# Site global metrics
SITE_METRICS_CONFIGS = []
# Deep Teletraan backend health check url
TELETRAAN_SERVICE_HEALTHCHECK_URL = os.getenv("TELETRAAN_SERVICE_HEALTHCHECK_URL", None)

# Show hosts that are STOPPING or STOPPED in the environments page
DISPLAY_STOPPING_HOSTS = os.getenv("DISPLAY_STOPPING_HOSTS", "true")

# Pinterest specific settings
IS_PINTEREST = True if os.getenv("IS_PINTEREST", "false") == "true" else False
BUILD_URL = "https://jenkins.pinadmin.com/job/"

TELETRAAN_DISABLE_CREATE_ENV_PAGE = True if os.getenv("TELETRAAN_DISABLE_CREATE_ENV_PAGE", "false") == "true" else False
TELETRAAN_REDIRECT_CREATE_ENV_PAGE_URL = os.getenv("TELETRAAN_REDIRECT_CREATE_ENV_PAGE_URL", None)
IS_DURING_CODE_FREEZE = True if os.getenv("TELETRAAN_CODE_FREEZE", "false") == "true" else False
TELETRAAN_CODE_FREEZE_URL = os.getenv("TELETRAAN_CODE_FREEZE_URL", None)
TELETRAAN_JIRA_SOURCE_URL = os.getenv("TELETRAAN_JIRA_SOURCE_URL", None)

# use Rodimus if present
RODIMUS_SERVICE_URL = os.getenv("RODIMUS_SERVICE_URL", None)
RODIMUS_SERVICE_VERSION = os.getenv("RODIMUS_SERVICE_VERSION", None)

if IS_PINTEREST:
    # use knox if present
    KNOX_SESSION_ID = os.getenv("KNOX_SESSION_ID")
    if KNOX_SESSION_ID:
        from knox import Knox

        SECRET_KEY = Knox().get_primary(KNOX_SESSION_ID)

    ADMIN_OAUTH_SECRET_KNOX_ID = os.getenv("ADMIN_OAUTH_SECRET_KNOX_ID")
    if ADMIN_OAUTH_SECRET_KNOX_ID:
        from knox import Knox

        OAUTH_CLIENT_SECRET = Knox().get_primary(ADMIN_OAUTH_SECRET_KNOX_ID)

    # Site health metrics
    REQUESTS_URL = os.getenv("REQUESTS_URL")
    SUCCESS_RATE_URL = os.getenv("SUCCESS_RATE_URL")
    LATENCY_URL = os.getenv("LATENCY_URL")
    SITE_METRICS_CONFIGS = [
        {"title": "Requests", "url": REQUESTS_URL,
         "specs": [{"min": 0, "max": 50000, "color": "Red"},
                   {"min": 50000, "max": 80000, "color": "Yellow"},
                   {"min": 80000, "max": 200000, "color": "Green"}]},
        {"title": "Success", "url": SUCCESS_RATE_URL,
         "specs": [{"min": 90, "max": 98, "color": "Red"},
                   {"min": 98, "max": 99, "color": "Yellow"},
                   {"min": 99, "max": 100, "color": "Green"}]},
        {"title": "Latency", "url": LATENCY_URL,
         "specs": [{"min": 800, "max": 1000, "color": "Red"},
                   {"min": 600, "max": 800, "color": "Yellow"},
                   {"min": 300, "max": 600, "color": "Green"}]}
    ]

    # Pinterest ngapp2 status file
    NGAPP_PRE_DEPLOY_STATUS_NODE = "varnish_pre_deploy_status"
    NGAPP_POST_DEPLOY_STATUS_NODE = "varnish_post_deploy_status"
    NGAPP_ROLLBACK_STATUS_NODE = "varnish_rollback_status"
    NGAPP_DEPLOY_CHANNEL = "deploys"

    DEFAULT_START_TIME = "-1d"

    #Pinterest Default Cloud Provider
    DEFAULT_PROVIDER = 'AWS'

    #Pinterest Default AMI image name
    DEFAULT_CMP_IMAGE = 'cmp_base'

    #Pinterest Default Host Type
    DEFAULT_CMP_HOST_TYPE = 'ComputeLo'

    DEFAULT_CELL = 'aws-us-east-1'
    DEFAULT_PLACEMENT = os.getenv('DEFAULT_CMP_PLACEMENT')

    #Pinterest Default Puppet Environment
    DEFAULT_CMP_PINFO_ENVIRON = os.getenv('DEFAULT_CMP_PINFO_ENVIRON')
    DEFAULT_CMP_ACCESS_ROLE = os.getenv('DEFAULT_CMP_ACCESS_ROLE')

<commit_msg>update default host type to new gen of computeLo (#611)<commit_after># Copyright 2016 Pinterest, Inc.
#
# 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.

"""
Django settings for deploy_board project.

For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import logging

logger = logging.getLogger(__name__)

BASE_DIR = os.path.dirname(__file__)

PROJECT_PATH = BASE_DIR

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
)

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("SECRET_KEY", None)
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
# OAuth
OAUTH_ENABLED_STR = os.getenv("OAUTH_ENABLED", "OFF")
if OAUTH_ENABLED_STR == "OFF":
    OAUTH_ENABLED = False
else:
    OAUTH_ENABLED = True
    OAUTH_CLIENT_ID = os.getenv("OAUTH_CLIENT_ID")
    OAUTH_CLIENT_SECRET = os.getenv("OAUTH_CLIENT_SECRET")
    OAUTH_CALLBACK = os.getenv("OAUTH_CALLBACK")
    OAUTH_DOMAIN = os.getenv("OAUTH_DOMAIN")
    OAUTH_CLIENT_TYPE = os.getenv("OAUTH_CLIENT_TYPE")
    OAUTH_USER_INFO_URI = os.getenv("OAUTH_USER_INFO_URI")
    OAUTH_USER_INFO_KEY = os.getenv("OAUTH_USER_INFO_KEY")
    OAUTH_ACCESS_TOKEN_URL = os.getenv("OAUTH_ACCESS_TOKEN_URL")
    OAUTH_AUTHORIZE_URL = os.getenv("OAUTH_AUTHORIZE_URL")
    OAUTH_DEFAULT_SCOPE = os.getenv("OAUTH_DEFAULT_SCOPE")
    OAUTH_USERNAME_INFO_KEY = os.getenv("OAUTH_USERNAME_INFO_KEY")
    OAUTH_EXTRACT_USERNAME_FROM_EMAIL = os.getenv("OAUTH_EXTRACT_USERNAME_FROM_EMAIL")

# Teletraan backend service url
TELETRAAN_SERVICE_URL = os.getenv("TELETRAAN_SERVICE_URL")
TELETRAAN_SERVICE_VERSION = os.getenv("TELETRAAN_SERVICE_VERSION")
TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN = os.getenv("TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN", None)
TELETRAAN_HOST_INFORMATION_URL = os.getenv("HOST_INFORMATION_URL")

# CMDB vars
CMDB_API_HOST = os.getenv("CMDB_API_HOST", "http://localhost:8080/")
CMDB_INSTANCE_URL = os.getenv("CMDB_INSTANCE_URL", "api/cmdb/getinstance/")
CMDB_UI_HOST = os.getenv("CMDB_UI_HOST", "localhost")
PHOBOS_URL = os.getenv("PHOBOS_URL")

# Serviceframework add-on vars
SERVICE_RATELIMIT_CONFIG_URL = os.getenv("SERVICE_RATELIMIT_CONFIG_URL")
STATSBOARD_API_FORMAT = os.getenv("STATSBOARD_API_FORMAT", "OFF")
RATELIMIT_ENABLED_METRIC_FORMAT = os.getenv("RATELIMIT_ENABLED_METRIC_FORMAT", "OFF")
ENABLING_SERVICE_RATELIMIT_URL = os.getenv("ENABLING_SERVICE_RATELIMIT_URL", "OFF")
KAFKA_MSGS_DELIVERED_METRIC = os.getenv("KAFKA_MSGS_DELIVERED_METRIC", "OFF")
DASHBOARD_URL_ENDPOINT_FORMAT = os.getenv("DASHBOARD_URL_ENDPOINT_FORMAT","OFF")

# For rolling out new features
GUINEA_PIG_ENVS = os.getenv("GUINEA_PIG_ENVS", "").split(",")
KAFKA_LOGGING_ADD_ON_ENVS = os.getenv("KAFKA_LOGGING_ADD_ON_ENVS", "").split(",")

LOG_DIR = os.getenv("LOG_DIR")
LOG_LEVEL = os.getenv("LOG_LEVEL")

# Change to your domain or hosts
if LOG_LEVEL == 'DEBUG':
    DEBUG = True
    TEMPLATE_DEBUG = True
    ALLOWED_HOSTS = []
else:
    ALLOWED_HOSTS = ['*']

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level': LOG_LEVEL,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': '%s/service.log' % LOG_DIR,
            'maxBytes': 1024 * 1024 * 5,  # 5 MB
            'backupCount': 5,
            'formatter': 'standard',
        },
        'request_handler': {
            'level': LOG_LEVEL,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': '%s/access.log' % LOG_DIR,
            'maxBytes': 1024 * 1024 * 5,  # 5 MB
            'backupCount': 5,
            'formatter': 'standard',
        },
        'console': {
            'level': LOG_LEVEL,
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default', 'console'],
            'level': LOG_LEVEL,
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': LOG_LEVEL,
            'propagate': False
        },
    }
}

# Application definition
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'deploy_board.webapp',
)

oauth_middleware = 'deploy_board.webapp.security.DelegatedOAuthMiddleware'
if TELETRAAN_SERVICE_FIXED_OAUTH_TOKEN:
    oauth_middleware = 'deploy_board.webapp.security.FixedOAuthMiddleware'

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    oauth_middleware,
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'deploy_board.webapp.error_views.ExceptionHandlerMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.static",
    "django.contrib.messages.context_processors.messages",
    "django.core.context_processors.request",
)

ROOT_URLCONF = 'deploy_board.urls'

WSGI_APPLICATION = 'deploy_board.wsgi.application'

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# The number of days since the build publish date required to trigger an old build version warning message
OLD_BUILD_WARNING_THRESHOLD_DAYS = 10

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(PROJECT_PATH, "static"),
)
#STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

# Site global metrics
SITE_METRICS_CONFIGS = []
# Deep Teletraan backend health check url
TELETRAAN_SERVICE_HEALTHCHECK_URL = os.getenv("TELETRAAN_SERVICE_HEALTHCHECK_URL", None)

# Show hosts that are STOPPING or STOPPED in the environments page
DISPLAY_STOPPING_HOSTS = os.getenv("DISPLAY_STOPPING_HOSTS", "true")

# Pinterest specific settings
IS_PINTEREST = True if os.getenv("IS_PINTEREST", "false") == "true" else False
BUILD_URL = "https://jenkins.pinadmin.com/job/"

TELETRAAN_DISABLE_CREATE_ENV_PAGE = True if os.getenv("TELETRAAN_DISABLE_CREATE_ENV_PAGE", "false") == "true" else False
TELETRAAN_REDIRECT_CREATE_ENV_PAGE_URL = os.getenv("TELETRAAN_REDIRECT_CREATE_ENV_PAGE_URL", None)
IS_DURING_CODE_FREEZE = True if os.getenv("TELETRAAN_CODE_FREEZE", "false") == "true" else False
TELETRAAN_CODE_FREEZE_URL = os.getenv("TELETRAAN_CODE_FREEZE_URL", None)
TELETRAAN_JIRA_SOURCE_URL = os.getenv("TELETRAAN_JIRA_SOURCE_URL", None)

# use Rodimus if present
RODIMUS_SERVICE_URL = os.getenv("RODIMUS_SERVICE_URL", None)
RODIMUS_SERVICE_VERSION = os.getenv("RODIMUS_SERVICE_VERSION", None)

if IS_PINTEREST:
    # use knox if present
    KNOX_SESSION_ID = os.getenv("KNOX_SESSION_ID")
    if KNOX_SESSION_ID:
        from knox import Knox

        SECRET_KEY = Knox().get_primary(KNOX_SESSION_ID)

    ADMIN_OAUTH_SECRET_KNOX_ID = os.getenv("ADMIN_OAUTH_SECRET_KNOX_ID")
    if ADMIN_OAUTH_SECRET_KNOX_ID:
        from knox import Knox

        OAUTH_CLIENT_SECRET = Knox().get_primary(ADMIN_OAUTH_SECRET_KNOX_ID)

    # Site health metrics
    REQUESTS_URL = os.getenv("REQUESTS_URL")
    SUCCESS_RATE_URL = os.getenv("SUCCESS_RATE_URL")
    LATENCY_URL = os.getenv("LATENCY_URL")
    SITE_METRICS_CONFIGS = [
        {"title": "Requests", "url": REQUESTS_URL,
         "specs": [{"min": 0, "max": 50000, "color": "Red"},
                   {"min": 50000, "max": 80000, "color": "Yellow"},
                   {"min": 80000, "max": 200000, "color": "Green"}]},
        {"title": "Success", "url": SUCCESS_RATE_URL,
         "specs": [{"min": 90, "max": 98, "color": "Red"},
                   {"min": 98, "max": 99, "color": "Yellow"},
                   {"min": 99, "max": 100, "color": "Green"}]},
        {"title": "Latency", "url": LATENCY_URL,
         "specs": [{"min": 800, "max": 1000, "color": "Red"},
                   {"min": 600, "max": 800, "color": "Yellow"},
                   {"min": 300, "max": 600, "color": "Green"}]}
    ]

    # Pinterest ngapp2 status file
    NGAPP_PRE_DEPLOY_STATUS_NODE = "varnish_pre_deploy_status"
    NGAPP_POST_DEPLOY_STATUS_NODE = "varnish_post_deploy_status"
    NGAPP_ROLLBACK_STATUS_NODE = "varnish_rollback_status"
    NGAPP_DEPLOY_CHANNEL = "deploys"

    DEFAULT_START_TIME = "-1d"

    #Pinterest Default Cloud Provider
    DEFAULT_PROVIDER = 'AWS'

    #Pinterest Default AMI image name
    DEFAULT_CMP_IMAGE = 'cmp_base'

    #Pinterest Default Host Type
    DEFAULT_CMP_HOST_TYPE = 'ComputeLo(new Gen)'

    DEFAULT_CELL = 'aws-us-east-1'
    DEFAULT_PLACEMENT = os.getenv('DEFAULT_CMP_PLACEMENT')

    #Pinterest Default Puppet Environment
    DEFAULT_CMP_PINFO_ENVIRON = os.getenv('DEFAULT_CMP_PINFO_ENVIRON')
    DEFAULT_CMP_ACCESS_ROLE = os.getenv('DEFAULT_CMP_ACCESS_ROLE')

<|endoftext|>


<commit_before>import os
from time import sleep

import pytest
import redis

from django_q.brokers import get_broker, Broker
from django_q.conf import Conf
from django_q.humanhash import uuid

def test_broker(monkeypatch):
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.lock_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    # stats
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'
    # stats with no cache
    monkeypatch.setattr(Conf, 'CACHE', 'not_configured')
    broker.cache = broker.get_cache()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') is None
    assert broker.get_stats('test:*') is None

def test_redis(monkeypatch):
    monkeypatch.setattr(Conf, 'DJANGO_REDIS', None)
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    monkeypatch.setattr(Conf, 'REDIS', {'host': '127.0.0.1', 'port': 7799})
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()

def test_custom(monkeypatch):
    monkeypatch.setattr(Conf, 'BROKER_CLASS', 'brokers.redis_broker.Redis')
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.__class__.__name__ == 'Redis'

def test_disque(monkeypatch):
    monkeypatch.setattr(Conf, 'DISQUE_NODES', ['127.0.0.1:7711'])
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    monkeypatch.setattr(Conf, 'DISQUE_FASTACK', True)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    monkeypatch.setattr(Conf, 'DISQUE_NODES', ['127.0.0.1:7798', '127.0.0.1:7799'])
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq(monkeypatch):
    monkeypatch.setattr(Conf, 'IRON_MQ', {'token': os.getenv('IRON_MQ_TOKEN'),
                                          'project_id': os.getenv('IRON_MQ_PROJECT_ID')})
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    # monkeypatch.setattr(Conf, 'RETRY', 1)
    # broker.enqueue('test')
    # assert broker.dequeue() is not None
    # sleep(3)
    # assert broker.dequeue() is not None
    # task = broker.dequeue()[0]
    # assert len(task) > 0
    # broker.acknowledge(task[0])
    # sleep(3)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs(monkeypatch):
    monkeypatch.setattr(Conf, 'SQS', {'aws_region': os.getenv('AWS_REGION'),
                                      'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                                      'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')})
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    sleep(2)
    # Sometimes SQS is not linear
    task = broker.dequeue()
    if not task:
        pytest.skip('SQS being weird')
    task = task[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(2)
    # delete job
    broker.enqueue('test')
    task_id = broker.dequeue()[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 12)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    assert broker.lock_size() == 0
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()

@pytest.mark.django_db
def test_orm(monkeypatch):
    monkeypatch.setattr(Conf, 'ORM', 'default')
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    tasks = broker.dequeue()
    assert broker.lock_size() == Conf.BULK
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0

@pytest.mark.django_db
def test_mongo(monkeypatch):
    monkeypatch.setattr(Conf, 'MONGO', {'host': '127.0.0.1', 'port': 27017})
    # check broker
    broker = get_broker(list_key='mongo_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    tasks = []
    for i in range(5):
        tasks.append(broker.dequeue()[0])
    assert broker.lock_size() == 5
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    assert broker.queue_size() == 0
<commit_msg>Skip SQS test for now<commit_after>import os
from time import sleep

import pytest
import redis

from django_q.brokers import get_broker, Broker
from django_q.conf import Conf
from django_q.humanhash import uuid

def test_broker(monkeypatch):
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.lock_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    # stats
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'
    # stats with no cache
    monkeypatch.setattr(Conf, 'CACHE', 'not_configured')
    broker.cache = broker.get_cache()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') is None
    assert broker.get_stats('test:*') is None

def test_redis(monkeypatch):
    monkeypatch.setattr(Conf, 'DJANGO_REDIS', None)
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    monkeypatch.setattr(Conf, 'REDIS', {'host': '127.0.0.1', 'port': 7799})
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()

def test_custom(monkeypatch):
    monkeypatch.setattr(Conf, 'BROKER_CLASS', 'brokers.redis_broker.Redis')
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.__class__.__name__ == 'Redis'

def test_disque(monkeypatch):
    monkeypatch.setattr(Conf, 'DISQUE_NODES', ['127.0.0.1:7711'])
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    monkeypatch.setattr(Conf, 'DISQUE_FASTACK', True)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    monkeypatch.setattr(Conf, 'DISQUE_NODES', ['127.0.0.1:7798', '127.0.0.1:7799'])
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq(monkeypatch):
    monkeypatch.setattr(Conf, 'IRON_MQ', {'token': os.getenv('IRON_MQ_TOKEN'),
                                          'project_id': os.getenv('IRON_MQ_PROJECT_ID')})
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    # monkeypatch.setattr(Conf, 'RETRY', 1)
    # broker.enqueue('test')
    # assert broker.dequeue() is not None
    # sleep(3)
    # assert broker.dequeue() is not None
    # task = broker.dequeue()[0]
    # assert len(task) > 0
    # broker.acknowledge(task[0])
    # sleep(3)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs(monkeypatch):
    monkeypatch.setattr(Conf, 'SQS', {'aws_region': os.getenv('AWS_REGION'),
                                      'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                                      'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')})
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    sleep(2)
    # Sometimes SQS is not linear
    task = broker.dequeue()
    if not task:
        pytest.skip('SQS being weird')
    task = task[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(2)
    # delete job
    monkeypatch.setattr(Conf, 'RETRY', 60)
    broker.enqueue('test')
    sleep(1)
    task = broker.dequeue()
    if not task:
        pytest.skip('SQS being weird')
    task_id = task[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 12)
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    assert broker.lock_size() == 0
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()

@pytest.mark.django_db
def test_orm(monkeypatch):
    monkeypatch.setattr(Conf, 'ORM', 'default')
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    monkeypatch.setattr(Conf, 'BULK', 5)
    tasks = broker.dequeue()
    assert broker.lock_size() == Conf.BULK
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0

@pytest.mark.django_db
def test_mongo(monkeypatch):
    monkeypatch.setattr(Conf, 'MONGO', {'host': '127.0.0.1', 'port': 27017})
    # check broker
    broker = get_broker(list_key='mongo_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    monkeypatch.setattr(Conf, 'RETRY', 1)
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    tasks = []
    for i in range(5):
        tasks.append(broker.dequeue()[0])
    assert broker.lock_size() == 5
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    assert broker.queue_size() == 0
<|endoftext|>


<commit_before>from time import sleep
import pytest
import os
import redis
from django_q.conf import Conf
from django_q.brokers import get_broker, Broker
from django_q.humanhash import uuid

def test_broker():
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'

def test_redis():
    Conf.DJANGO_REDIS = None
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    Conf.REDIS = {'host': '127.0.0.1', 'port': 7799}
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()
    Conf.REDIS = None
    Conf.DJANGO_REDIS = 'default'

def test_disque():
    Conf.DISQUE_NODES = ['127.0.0.1:7711']
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    Conf.DISQUE_FASTACK = True
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    Conf.DISQUE_NODES = ['127.0.0.1:7798', '127.0.0.1:7799']
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()
    # back to django-redis
    Conf.DISQUE_NODES = None
    Conf.DISQUE_FASTACK = False

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq():
    Conf.DISQUE_NODES = None
    Conf.SQS = None
    Conf.IRON_MQ = {'token': os.getenv('IRON_MQ_TOKEN'),
                    'project_id': os.getenv('IRON_MQ_PROJECT_ID')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(1.5)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(1.5)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()
    # back to django-redis
    Conf.IRON_MQ = None
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs():
    Conf.IRON_MQ = None
    Conf.DISQUE_NODES = None
    Conf.SQS = {'aws_region': os.getenv('AWS_REGION'),
                'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(1.5)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(1.5)
    # delete job
    broker.enqueue('test')
    task_id = broker.dequeue()[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    Conf.BULK = 12
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    # back to django-redis
    Conf.SQS = None
    Conf.BULK = 1
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.django_db
def test_orm():
    Conf.ORM = 'default'
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None
<commit_msg>Tests no cache configuration<commit_after>from time import sleep
import pytest
import os
import redis
from django_q.conf import Conf
from django_q.brokers import get_broker, Broker
from django_q.humanhash import uuid

def test_broker():
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    # stats
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'
    # stats with no cache
    Conf.CACHE = 'not_configured'
    broker.cache = broker.get_cache()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') is None
    assert broker.get_stats('test:*') is None
    Conf.CACHE = 'default'

def test_redis():
    Conf.DJANGO_REDIS = None
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    Conf.REDIS = {'host': '127.0.0.1', 'port': 7799}
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()
    Conf.REDIS = None
    Conf.DJANGO_REDIS = 'default'

def test_disque():
    Conf.DISQUE_NODES = ['127.0.0.1:7711']
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    Conf.DISQUE_FASTACK = True
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    Conf.DISQUE_NODES = ['127.0.0.1:7798', '127.0.0.1:7799']
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()
    # back to django-redis
    Conf.DISQUE_NODES = None
    Conf.DISQUE_FASTACK = False

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq():
    Conf.DISQUE_NODES = None
    Conf.SQS = None
    Conf.IRON_MQ = {'token': os.getenv('IRON_MQ_TOKEN'),
                    'project_id': os.getenv('IRON_MQ_PROJECT_ID')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(1.5)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(1.5)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()
    # back to django-redis
    Conf.IRON_MQ = None
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs():
    Conf.IRON_MQ = None
    Conf.DISQUE_NODES = None
    Conf.SQS = {'aws_region': os.getenv('AWS_REGION'),
                'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(1.5)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(1.5)
    # delete job
    broker.enqueue('test')
    task_id = broker.dequeue()[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    Conf.BULK = 12
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    # back to django-redis
    Conf.SQS = None
    Conf.BULK = 1
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.django_db
def test_orm():
    Conf.ORM = 'default'
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None
<|endoftext|>


<commit_before>import datetime

from django.forms.widgets import Widget, Input
from django.utils.dates import MONTHS
from django.utils.datastructures import SortedDict

class RemoteWidget(object):
    def __init__(self, widget, name=None):
        self.widget = widget
        self.name = name or self.widget.__class__.__name__

    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.name
        widget_dict['is_hidden'] = self.widget.is_hidden
        widget_dict['needs_multipart_form'] = self.widget.needs_multipart_form
        widget_dict['is_localized'] = self.widget.is_localized
        widget_dict['is_required'] = self.widget.is_required
        widget_dict['attrs'] = self.widget.build_attrs()

        return widget_dict

class RemoteInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteInput, self).as_dict()
        widget_dict['input_type'] = self.widget.input_type
        return widget_dict

class RemoteTextInput(RemoteInput):
    def as_dict(self):
        return super(RemoteTextInput, self).as_dict()

class RemotePasswordInput(RemoteInput):
    def as_dict(self):
        return super(RemotePasswordInput, self).as_dict()

class RemoteHiddenInput(RemoteInput):
    def as_dict(self):
        return super(RemoteHiddenInput, self).as_dict()

class RemoteMultipleHiddenInput(RemoteHiddenInput):
    def as_dict(self):
        widget_dict = super(RemoteMultipleHiddenInput, self).as_dict()
        widget_dict['choices'] = self.choices
        return widget_dict

class RemoteFileInput(RemoteInput):
    def as_dict(self):
        return super(RemoteFileInput, self).as_dict()

class RemoteClearableFileInput(RemoteFileInput):
    def as_dict(self):
        widget_dict = super(RemoteClearableFileInput, self).as_dict()
        widget_dict['initial_text'] = self.initial_text
        widget_dict['input_text'] = self.input_text
        widget_dict['clear_checkbox_label'] = self.clear_checkbox_label
        return widget_dict

class RemoteTextarea(RemoteInput):
    def as_dict(self):
        widget_dict = super(RemoteTextarea, self).as_dict()
        widget_dict['input_type'] = 'textarea'
        return widget_dict

class RemoteTimeInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteTimeInput, self).as_dict()

        widget_dict['format'] = self.widget.format
        widget_dict['manual_format'] = self.widget.manual_format
        widget_dict['date'] = self.widget.manual_format
        widget_dict['input_type'] = 'time'
        return widget_dict

class RemoteDateInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteDateInput, self).as_dict()

        widget_dict['input_type'] = 'date'

        years = self.widget.years
        if not callable(self.widget.years):
            years = lambda: self.widget.years

        current_year = datetime.datetime.now().year
        widget_dict['choices'] = [{
            'title': 'day',
            'data': [{'key': x, 'value': x} for x in range(1, 32)]
        }, {
            'title': 'month',
            'data': [{'key': x, 'value': y} for (x, y) in MONTHS.items()]
        }, {
            'title': 'year',
            'data': [{'key': x, 'value': x} for x in years()]
        }]
        return widget_dict

class RemoteDateTimeInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteDateTimeInput, self).as_dict()

        widget_dict['input_type'] = 'datetime'
        return widget_dict

class RemoteCheckboxInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteCheckboxInput, self).as_dict()

        # If check test is None then the input should accept null values
        check_test = None
        if self.check_test is not None:
            check_test = True

        widget_dict['check_test'] = check_test
        widget_dict['input_type'] = 'checkbox'
        return widget_dict

class RemoteSelect(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteSelect, self).as_dict()

        widget_dict['choices'] = []
        for key, value in self.choices:
            widget_dict['choices'].append({
                'value': key,
                'display': value
            })

        widget_dict['input_type'] = 'select'
        return widget_dict

class RemoteNullBooleanSelect(RemoteSelect):
    def as_dict(self):
        return super(RemoteNullBooleanSelect, self).as_dict()

class RemoteSelectMultiple(RemoteSelect):
    def as_dict(self):
        widget_dict = super(RemoteSelectMultiple, self).as_dict()

        widget_dict['input_type'] = 'selectmultiple'
        widget_dict['size'] = len(widget_dict['choices'])
        return widget_dict

class RemoteRadioInput(RemoteWidget):
    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.__class__.__name__
        widget_dict['name'] = self.name
        widget_dict['value'] = self.value
        widget_dict['attrs'] = self.attrs
        widget_dict['choice_value'] = self.choice_value
        widget_dict['choice_label'] = self.choice_label
        widget_dict['index'] = self.index
        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteRadioFieldRenderer(RemoteWidget):
    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.__class__.__name__
        widget_dict['name'] = self.name
        widget_dict['value'] = self.value
        widget_dict['attrs'] = self.attrs
        widget_dict['choices'] = self.choices
        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteRadioSelect(RemoteSelect):
    def as_dict(self):
        widget_dict = super(RemoteRadioSelect, self).as_dict()

        widget_dict['choices'] = []
        for key, value in self.choices:
            widget_dict['choices'].append({
                'name': self.field_name or '',
                'value': key,
                'display': value
            })

        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteCheckboxSelectMultiple(RemoteSelectMultiple):
    def as_dict(self):
        return super(RemoteCheckboxSelectMultiple, self).as_dict()

class RemoteMultiWidget(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteMultiWidget, self).as_dict()

        widget_list = []
        for widget in self.widgets:
            # Fetch remote widget and convert to dict
            widget_list.append()

        widget_dict['widgets'] = widget_list
        return widget_dict

class RemoteSplitDateTimeWidget(RemoteMultiWidget):
    def as_dict(self):
        widget_dict = super(RemoteSplitDateTimeWidget, self).as_dict()

        widget_dict['date_format'] = self.date_format
        widget_dict['time_format'] = self.time_format

        return widget_dict

class RemoteSplitHiddenDateTimeWidget(RemoteSplitDateTimeWidget):
    def as_dict(self):
        return super(RemoteSplitHiddenDateTimeWidget, self).as_dict()
<commit_msg>Fix broken check_test reference<commit_after>import datetime

from django.forms.widgets import Widget, Input
from django.utils.dates import MONTHS
from django.utils.datastructures import SortedDict

class RemoteWidget(object):
    def __init__(self, widget, name=None):
        self.widget = widget
        self.name = name or self.widget.__class__.__name__

    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.name
        widget_dict['is_hidden'] = self.widget.is_hidden
        widget_dict['needs_multipart_form'] = self.widget.needs_multipart_form
        widget_dict['is_localized'] = self.widget.is_localized
        widget_dict['is_required'] = self.widget.is_required
        widget_dict['attrs'] = self.widget.build_attrs()

        return widget_dict

class RemoteInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteInput, self).as_dict()
        widget_dict['input_type'] = self.widget.input_type
        return widget_dict

class RemoteTextInput(RemoteInput):
    def as_dict(self):
        return super(RemoteTextInput, self).as_dict()

class RemotePasswordInput(RemoteInput):
    def as_dict(self):
        return super(RemotePasswordInput, self).as_dict()

class RemoteHiddenInput(RemoteInput):
    def as_dict(self):
        return super(RemoteHiddenInput, self).as_dict()

class RemoteMultipleHiddenInput(RemoteHiddenInput):
    def as_dict(self):
        widget_dict = super(RemoteMultipleHiddenInput, self).as_dict()
        widget_dict['choices'] = self.choices
        return widget_dict

class RemoteFileInput(RemoteInput):
    def as_dict(self):
        return super(RemoteFileInput, self).as_dict()

class RemoteClearableFileInput(RemoteFileInput):
    def as_dict(self):
        widget_dict = super(RemoteClearableFileInput, self).as_dict()
        widget_dict['initial_text'] = self.initial_text
        widget_dict['input_text'] = self.input_text
        widget_dict['clear_checkbox_label'] = self.clear_checkbox_label
        return widget_dict

class RemoteTextarea(RemoteInput):
    def as_dict(self):
        widget_dict = super(RemoteTextarea, self).as_dict()
        widget_dict['input_type'] = 'textarea'
        return widget_dict

class RemoteTimeInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteTimeInput, self).as_dict()

        widget_dict['format'] = self.widget.format
        widget_dict['manual_format'] = self.widget.manual_format
        widget_dict['date'] = self.widget.manual_format
        widget_dict['input_type'] = 'time'
        return widget_dict

class RemoteDateInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteDateInput, self).as_dict()

        widget_dict['input_type'] = 'date'

        years = self.widget.years
        if not callable(self.widget.years):
            years = lambda: self.widget.years

        current_year = datetime.datetime.now().year
        widget_dict['choices'] = [{
            'title': 'day',
            'data': [{'key': x, 'value': x} for x in range(1, 32)]
        }, {
            'title': 'month',
            'data': [{'key': x, 'value': y} for (x, y) in MONTHS.items()]
        }, {
            'title': 'year',
            'data': [{'key': x, 'value': x} for x in years()]
        }]
        return widget_dict

class RemoteDateTimeInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteDateTimeInput, self).as_dict()

        widget_dict['input_type'] = 'datetime'
        return widget_dict

class RemoteCheckboxInput(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteCheckboxInput, self).as_dict()

        # If check test is None then the input should accept null values
        check_test = None
        if self.widget.check_test is not None:
            check_test = True

        widget_dict['check_test'] = check_test
        widget_dict['input_type'] = 'checkbox'
        return widget_dict

class RemoteSelect(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteSelect, self).as_dict()

        widget_dict['choices'] = []
        for key, value in self.choices:
            widget_dict['choices'].append({
                'value': key,
                'display': value
            })

        widget_dict['input_type'] = 'select'
        return widget_dict

class RemoteNullBooleanSelect(RemoteSelect):
    def as_dict(self):
        return super(RemoteNullBooleanSelect, self).as_dict()

class RemoteSelectMultiple(RemoteSelect):
    def as_dict(self):
        widget_dict = super(RemoteSelectMultiple, self).as_dict()

        widget_dict['input_type'] = 'selectmultiple'
        widget_dict['size'] = len(widget_dict['choices'])
        return widget_dict

class RemoteRadioInput(RemoteWidget):
    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.__class__.__name__
        widget_dict['name'] = self.name
        widget_dict['value'] = self.value
        widget_dict['attrs'] = self.attrs
        widget_dict['choice_value'] = self.choice_value
        widget_dict['choice_label'] = self.choice_label
        widget_dict['index'] = self.index
        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteRadioFieldRenderer(RemoteWidget):
    def as_dict(self):
        widget_dict = SortedDict()
        widget_dict['title'] = self.__class__.__name__
        widget_dict['name'] = self.name
        widget_dict['value'] = self.value
        widget_dict['attrs'] = self.attrs
        widget_dict['choices'] = self.choices
        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteRadioSelect(RemoteSelect):
    def as_dict(self):
        widget_dict = super(RemoteRadioSelect, self).as_dict()

        widget_dict['choices'] = []
        for key, value in self.choices:
            widget_dict['choices'].append({
                'name': self.field_name or '',
                'value': key,
                'display': value
            })

        widget_dict['input_type'] = 'radio'
        return widget_dict

class RemoteCheckboxSelectMultiple(RemoteSelectMultiple):
    def as_dict(self):
        return super(RemoteCheckboxSelectMultiple, self).as_dict()

class RemoteMultiWidget(RemoteWidget):
    def as_dict(self):
        widget_dict = super(RemoteMultiWidget, self).as_dict()

        widget_list = []
        for widget in self.widgets:
            # Fetch remote widget and convert to dict
            widget_list.append()

        widget_dict['widgets'] = widget_list
        return widget_dict

class RemoteSplitDateTimeWidget(RemoteMultiWidget):
    def as_dict(self):
        widget_dict = super(RemoteSplitDateTimeWidget, self).as_dict()

        widget_dict['date_format'] = self.date_format
        widget_dict['time_format'] = self.time_format

        return widget_dict

class RemoteSplitHiddenDateTimeWidget(RemoteSplitDateTimeWidget):
    def as_dict(self):
        return super(RemoteSplitHiddenDateTimeWidget, self).as_dict()
<|endoftext|>