<commit_before>"""Provides a sensor to track various status aspects of a UPS."""
import logging

from homeassistant.const import ATTR_STATE, CONF_RESOURCES, STATE_UNKNOWN
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import (
    COORDINATOR,
    DOMAIN,
    KEY_STATUS,
    KEY_STATUS_DISPLAY,
    PYNUT_DATA,
    PYNUT_FIRMWARE,
    PYNUT_MANUFACTURER,
    PYNUT_MODEL,
    PYNUT_NAME,
    PYNUT_UNIQUE_ID,
    SENSOR_DEVICE_CLASS,
    SENSOR_ICON,
    SENSOR_NAME,
    SENSOR_TYPES,
    SENSOR_UNIT,
    STATE_TYPES,
)

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the NUT sensors."""

    pynut_data = hass.data[DOMAIN][config_entry.entry_id]
    unique_id = pynut_data[PYNUT_UNIQUE_ID]
    manufacturer = pynut_data[PYNUT_MANUFACTURER]
    model = pynut_data[PYNUT_MODEL]
    firmware = pynut_data[PYNUT_FIRMWARE]
    name = pynut_data[PYNUT_NAME]
    coordinator = pynut_data[COORDINATOR]
    data = pynut_data[PYNUT_DATA]
    status = data.status

    entities = []

    if CONF_RESOURCES in config_entry.options:
        resources = config_entry.options[CONF_RESOURCES]
    else:
        resources = config_entry.data[CONF_RESOURCES]

    for resource in resources:
        sensor_type = resource.lower()

        # Display status is a special case that falls back to the status value
        # of the UPS instead.
        if sensor_type in status or (
            sensor_type == KEY_STATUS_DISPLAY and KEY_STATUS in status
        ):
            entities.append(
                NUTSensor(
                    coordinator,
                    data,
                    name.title(),
                    sensor_type,
                    unique_id,
                    manufacturer,
                    model,
                    firmware,
                )
            )
        else:
            _LOGGER.warning(
                "Sensor type: %s does not appear in the NUT status "
                "output, cannot add",
                sensor_type,
            )

    async_add_entities(entities, True)

class NUTSensor(CoordinatorEntity):
    """Representation of a sensor entity for NUT status values."""

    def __init__(
        self,
        coordinator,
        data,
        name,
        sensor_type,
        unique_id,
        manufacturer,
        model,
        firmware,
    ):
        """Initialize the sensor."""
        super().__init__(coordinator)
        self._type = sensor_type
        self._manufacturer = manufacturer
        self._firmware = firmware
        self._model = model
        self._device_name = name
        self._name = f"{name} {SENSOR_TYPES[sensor_type][SENSOR_NAME]}"
        self._unit = SENSOR_TYPES[sensor_type][SENSOR_UNIT]
        self._data = data
        self._unique_id = unique_id

    @property
    def device_info(self):
        """Device info for the ups."""
        if not self._unique_id:
            return None
        device_info = {
            "identifiers": {(DOMAIN, self._unique_id)},
            "name": self._device_name,
        }
        if self._model:
            device_info["model"] = self._model
        if self._manufacturer:
            device_info["manufacturer"] = self._manufacturer
        if self._firmware:
            device_info["sw_version"] = self._firmware
        return device_info

    @property
    def unique_id(self):
        """Sensor Unique id."""
        if not self._unique_id:
            return None
        return f"{self._unique_id}_{self._type}"

    @property
    def name(self):
        """Return the name of the UPS sensor."""
        return self._name

    @property
    def icon(self):
        """Icon to use in the frontend, if any."""
        if SENSOR_TYPES[self._type][SENSOR_DEVICE_CLASS]:
            # The UI will assign an icon
            # if it has a class
            return None
        return SENSOR_TYPES[self._type][SENSOR_ICON]

    @property
    def device_class(self):
        """Device class of the sensor."""
        return SENSOR_TYPES[self._type][SENSOR_DEVICE_CLASS]

    @property
    def state(self):
        """Return entity state from ups."""
        if not self._data.status:
            return None
        if self._type == KEY_STATUS_DISPLAY:
            return _format_display_state(self._data.status)
        return self._data.status.get(self._type)

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this entity, if any."""
        return self._unit

    @property
    def device_state_attributes(self):
        """Return the sensor attributes."""
        return {ATTR_STATE: _format_display_state(self._data.status)}

def _format_display_state(status):
    """Return UPS display state."""
    if status is None:
        return STATE_TYPES["OFF"]
    try:
        return " ".join(STATE_TYPES[state] for state in status[KEY_STATUS].split())
    except KeyError:
        return STATE_UNKNOWN
<commit_msg>change log level to info (#46823)<commit_after>"""Provides a sensor to track various status aspects of a UPS."""
import logging

from homeassistant.const import ATTR_STATE, CONF_RESOURCES, STATE_UNKNOWN
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import (
    COORDINATOR,
    DOMAIN,
    KEY_STATUS,
    KEY_STATUS_DISPLAY,
    PYNUT_DATA,
    PYNUT_FIRMWARE,
    PYNUT_MANUFACTURER,
    PYNUT_MODEL,
    PYNUT_NAME,
    PYNUT_UNIQUE_ID,
    SENSOR_DEVICE_CLASS,
    SENSOR_ICON,
    SENSOR_NAME,
    SENSOR_TYPES,
    SENSOR_UNIT,
    STATE_TYPES,
)

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the NUT sensors."""

    pynut_data = hass.data[DOMAIN][config_entry.entry_id]
    unique_id = pynut_data[PYNUT_UNIQUE_ID]
    manufacturer = pynut_data[PYNUT_MANUFACTURER]
    model = pynut_data[PYNUT_MODEL]
    firmware = pynut_data[PYNUT_FIRMWARE]
    name = pynut_data[PYNUT_NAME]
    coordinator = pynut_data[COORDINATOR]
    data = pynut_data[PYNUT_DATA]
    status = data.status

    entities = []

    if CONF_RESOURCES in config_entry.options:
        resources = config_entry.options[CONF_RESOURCES]
    else:
        resources = config_entry.data[CONF_RESOURCES]

    for resource in resources:
        sensor_type = resource.lower()

        # Display status is a special case that falls back to the status value
        # of the UPS instead.
        if sensor_type in status or (
            sensor_type == KEY_STATUS_DISPLAY and KEY_STATUS in status
        ):
            entities.append(
                NUTSensor(
                    coordinator,
                    data,
                    name.title(),
                    sensor_type,
                    unique_id,
                    manufacturer,
                    model,
                    firmware,
                )
            )
        else:
            _LOGGER.info(
                "Sensor type: %s does not appear in the NUT status "
                "output, cannot add",
                sensor_type,
            )

    async_add_entities(entities, True)

class NUTSensor(CoordinatorEntity):
    """Representation of a sensor entity for NUT status values."""

    def __init__(
        self,
        coordinator,
        data,
        name,
        sensor_type,
        unique_id,
        manufacturer,
        model,
        firmware,
    ):
        """Initialize the sensor."""
        super().__init__(coordinator)
        self._type = sensor_type
        self._manufacturer = manufacturer
        self._firmware = firmware
        self._model = model
        self._device_name = name
        self._name = f"{name} {SENSOR_TYPES[sensor_type][SENSOR_NAME]}"
        self._unit = SENSOR_TYPES[sensor_type][SENSOR_UNIT]
        self._data = data
        self._unique_id = unique_id

    @property
    def device_info(self):
        """Device info for the ups."""
        if not self._unique_id:
            return None
        device_info = {
            "identifiers": {(DOMAIN, self._unique_id)},
            "name": self._device_name,
        }
        if self._model:
            device_info["model"] = self._model
        if self._manufacturer:
            device_info["manufacturer"] = self._manufacturer
        if self._firmware:
            device_info["sw_version"] = self._firmware
        return device_info

    @property
    def unique_id(self):
        """Sensor Unique id."""
        if not self._unique_id:
            return None
        return f"{self._unique_id}_{self._type}"

    @property
    def name(self):
        """Return the name of the UPS sensor."""
        return self._name

    @property
    def icon(self):
        """Icon to use in the frontend, if any."""
        if SENSOR_TYPES[self._type][SENSOR_DEVICE_CLASS]:
            # The UI will assign an icon
            # if it has a class
            return None
        return SENSOR_TYPES[self._type][SENSOR_ICON]

    @property
    def device_class(self):
        """Device class of the sensor."""
        return SENSOR_TYPES[self._type][SENSOR_DEVICE_CLASS]

    @property
    def state(self):
        """Return entity state from ups."""
        if not self._data.status:
            return None
        if self._type == KEY_STATUS_DISPLAY:
            return _format_display_state(self._data.status)
        return self._data.status.get(self._type)

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this entity, if any."""
        return self._unit

    @property
    def device_state_attributes(self):
        """Return the sensor attributes."""
        return {ATTR_STATE: _format_display_state(self._data.status)}

def _format_display_state(status):
    """Return UPS display state."""
    if status is None:
        return STATE_TYPES["OFF"]
    try:
        return " ".join(STATE_TYPES[state] for state in status[KEY_STATUS].split())
    except KeyError:
        return STATE_UNKNOWN
<|endoftext|>


<commit_before>"""
Support for Adafruit DHT temperature and humidity sensor.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.dht/
"""
import logging
from datetime import timedelta

from homeassistant.const import TEMP_FAHRENHEIT
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.util.temperature import celsius_to_fahrenheit

# Update this requirement to upstream as soon as it supports Python 3.
REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/'
                '4101340de8d2457dd194bca1e8d11cbfc237e919.zip'
                '#Adafruit_DHT==1.1.0']

_LOGGER = logging.getLogger(__name__)
SENSOR_TYPES = {
    'temperature': ['Temperature', None],
    'humidity': ['Humidity', '%']
}
DEFAULT_NAME = "DHT Sensor"
# Return cached results if last scan was less then this time ago
# DHT11 is able to deliver data once per second, DHT22 once every two
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)

def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the DHT sensor."""
    # pylint: disable=import-error
    import Adafruit_DHT

    SENSOR_TYPES['temperature'][1] = hass.config.units.temperature_unit
    available_sensors = {
        "DHT11": Adafruit_DHT.DHT11,
        "DHT22": Adafruit_DHT.DHT22,
        "AM2302": Adafruit_DHT.AM2302
    }
    sensor = available_sensors[config['sensor']]

    pin = config['pin']

    if not sensor or not pin:
        _LOGGER.error(
            "Config error "
            "Please check your settings for DHT, sensor not supported.")
        return None

    data = DHTClient(Adafruit_DHT, sensor, pin)
    dev = []
    name = config.get('name', DEFAULT_NAME)

    try:
        for variable in config['monitored_conditions']:
            if variable not in SENSOR_TYPES:
                _LOGGER.error('Sensor type: "%s" does not exist', variable)
            else:
                dev.append(
                    DHTSensor(data, variable, SENSOR_TYPES[variable][1], name))
    except KeyError:
        pass

    add_devices(dev)

# pylint: disable=too-few-public-methods
class DHTSensor(Entity):
    """Implementation of the DHT sensor."""

    def __init__(self, dht_client, sensor_type, temp_unit, name):
        """Initialize the sensor."""
        self.client_name = name
        self._name = SENSOR_TYPES[sensor_type][0]
        self.dht_client = dht_client
        self.temp_unit = temp_unit
        self.type = sensor_type
        self._state = None
        self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
        self.update()

    @property
    def name(self):
        """Return the name of the sensor."""
        return '{} {}'.format(self.client_name, self._name)

    @property
    def state(self):
        """Return the state of the sensor."""
        return self._state

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this entity, if any."""
        return self._unit_of_measurement

    def update(self):
        """Get the latest data from the DHT and updates the states."""
        self.dht_client.update()
        data = self.dht_client.data

        if self.type == 'temperature':
            self._state = round(data['temperature'], 1)
            if self.temp_unit == TEMP_FAHRENHEIT:
                self._state = round(celsius_to_fahrenheit(data['temperature']),
                                    1)
        elif self.type == 'humidity':
            self._state = round(data['humidity'], 1)

class DHTClient(object):
    """Get the latest data from the DHT sensor."""

    def __init__(self, adafruit_dht, sensor, pin):
        """Initialize the sensor."""
        self.adafruit_dht = adafruit_dht
        self.sensor = sensor
        self.pin = pin
        self.data = dict()

    @Throttle(MIN_TIME_BETWEEN_UPDATES)
    def update(self):
        """Get the latest data the DHT sensor."""
        humidity, temperature = self.adafruit_dht.read_retry(self.sensor,
                                                             self.pin)
        if temperature:
            self.data['temperature'] = temperature
        if humidity:
            self.data['humidity'] = humidity
<commit_msg>Implemented range checking for temperature and humidity. Out-of-range… (#2805)<commit_after>"""
Support for Adafruit DHT temperature and humidity sensor.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.dht/
"""
import logging
from datetime import timedelta

from homeassistant.const import TEMP_FAHRENHEIT
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.util.temperature import celsius_to_fahrenheit

# Update this requirement to upstream as soon as it supports Python 3.
REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/'
                '4101340de8d2457dd194bca1e8d11cbfc237e919.zip'
                '#Adafruit_DHT==1.1.0']

_LOGGER = logging.getLogger(__name__)
SENSOR_TYPES = {
    'temperature': ['Temperature', None],
    'humidity': ['Humidity', '%']
}
DEFAULT_NAME = "DHT Sensor"
# Return cached results if last scan was less then this time ago
# DHT11 is able to deliver data once per second, DHT22 once every two
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)

def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the DHT sensor."""
    # pylint: disable=import-error
    import Adafruit_DHT

    SENSOR_TYPES['temperature'][1] = hass.config.units.temperature_unit
    available_sensors = {
        "DHT11": Adafruit_DHT.DHT11,
        "DHT22": Adafruit_DHT.DHT22,
        "AM2302": Adafruit_DHT.AM2302
    }
    sensor = available_sensors[config['sensor']]

    pin = config['pin']

    if not sensor or not pin:
        _LOGGER.error(
            "Config error "
            "Please check your settings for DHT, sensor not supported.")
        return None

    data = DHTClient(Adafruit_DHT, sensor, pin)
    dev = []
    name = config.get('name', DEFAULT_NAME)

    try:
        for variable in config['monitored_conditions']:
            if variable not in SENSOR_TYPES:
                _LOGGER.error('Sensor type: "%s" does not exist', variable)
            else:
                dev.append(
                    DHTSensor(data, variable, SENSOR_TYPES[variable][1], name))
    except KeyError:
        pass

    add_devices(dev)

# pylint: disable=too-few-public-methods
class DHTSensor(Entity):
    """Implementation of the DHT sensor."""

    def __init__(self, dht_client, sensor_type, temp_unit, name):
        """Initialize the sensor."""
        self.client_name = name
        self._name = SENSOR_TYPES[sensor_type][0]
        self.dht_client = dht_client
        self.temp_unit = temp_unit
        self.type = sensor_type
        self._state = None
        self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
        self.update()

    @property
    def name(self):
        """Return the name of the sensor."""
        return '{} {}'.format(self.client_name, self._name)

    @property
    def state(self):
        """Return the state of the sensor."""
        return self._state

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this entity, if any."""
        return self._unit_of_measurement

    def update(self):
        """Get the latest data from the DHT and updates the states."""
        self.dht_client.update()
        data = self.dht_client.data

        if self.type == 'temperature':
            temperature = round(data['temperature'], 1)
            if (temperature >= -20) and (temperature < 80):
                self._state = temperature
                if self.temp_unit == TEMP_FAHRENHEIT:
                    self._state = round(celsius_to_fahrenheit(temperature),
                                        1)
        elif self.type == 'humidity':
            humidity = round(data['humidity'], 1)
            if (humidity >= 0) and (humidity <= 100):
                self._state = humidity

class DHTClient(object):
    """Get the latest data from the DHT sensor."""

    def __init__(self, adafruit_dht, sensor, pin):
        """Initialize the sensor."""
        self.adafruit_dht = adafruit_dht
        self.sensor = sensor
        self.pin = pin
        self.data = dict()

    @Throttle(MIN_TIME_BETWEEN_UPDATES)
    def update(self):
        """Get the latest data the DHT sensor."""
        humidity, temperature = self.adafruit_dht.read_retry(self.sensor,
                                                             self.pin)
        if temperature:
            self.data['temperature'] = temperature
        if humidity:
            self.data['humidity'] = humidity
<|endoftext|>


<commit_before>#!/usr/bin/python
#
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.

#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

import os
import re
import StringIO
import subprocess
import sys
import zipfile

is_unix = not sys.platform.startswith('win')

if not is_unix:
    print "This script currently only supports unix-like systems"
    sys.exit(-1)

if os.path.exists('OvmfPkgX64.dsc'):
    os.chdir('..')

if not os.path.exists(os.path.join('OvmfPkg', 'OvmfPkgX64.dsc')):
    print "OvmfPkg/OvmfPkgX64.dsc doesn't exist"
    sys.exit(-1)

if 'TOOLCHAIN' in os.environ:
    TOOLCHAIN = os.environ['TOOLCHAIN']
else:
    TOOLCHAIN = 'GCC44'

def run_and_capture_output(args, checkExitCode = True):
    p = subprocess.Popen(args=args, stdout=subprocess.PIPE)
    stdout = p.stdout.read()
    ret_code = p.wait()
    if checkExitCode:
        assert ret_code == 0
    return stdout

def git_svn_info():
    dir = os.getcwd()
    os.chdir('OvmfPkg')
    stdout = run_and_capture_output(args=('git', 'svn', 'info'))
    os.chdir(dir)
    return stdout

def svn_info():
    dir = os.getcwd()
    os.chdir('OvmfPkg')
    stdout = run_and_capture_output(args=('svn', 'info'))
    os.chdir(dir)
    return stdout

def get_svn_info_output():
    if os.path.exists(os.path.join('OvmfPkg', '.svn')):
        return svn_info()
    else:
        return git_svn_info()

def get_revision():
    buf = get_svn_info_output()
    revision_re = re.compile('^Revision\:\s*(\d+)$', re.MULTILINE)
    mo = revision_re.search(buf)
    if mo is not None:
        return int(mo.group(1))

revision = get_revision()

newline_re = re.compile(r'(\n|\r\n|\r(?!\n))', re.MULTILINE)
def to_dos_text(str):
    return newline_re.sub('\r\n', str)

def gen_build_info():
    distro = run_and_capture_output(args=('lsb_release', '-sd')).strip()

    machine = run_and_capture_output(args=('uname', '-m')).strip()

    gcc_version = run_and_capture_output(args=('gcc', '--version'))
    gcc_version = gcc_version.split('\n')[0].split()[-1]

    ld_version = run_and_capture_output(args=('ld', '--version'))
    ld_version = ld_version.split('\n')[0].split()[-1]

    iasl_version = run_and_capture_output(args=('iasl'), checkExitCode=False)
    iasl_version = filter(lambda s: s.find(' version ') >= 0, iasl_version.split('\n'))[0]
    iasl_version = iasl_version.split(' version ')[1].strip()

    sb = StringIO.StringIO()
    print >> sb, 'edk2:    ', 'r%d' % revision
    print >> sb, 'compiler: GCC', gcc_version
    print >> sb, 'binutils:', ld_version
    print >> sb, 'iasl:    ', iasl_version
    print >> sb, 'system:  ', distro, machine.replace('_', '-')
    return to_dos_text(sb.getvalue())

LICENSE = to_dos_text(
'''This OVMF binary release is built from source code licensed under
the BSD open source license.  The BSD license is documented at
http://opensource.org/licenses/bsd-license.php, and a copy is
shown below.

One sub-component of the OVMF project is a FAT filesystem driver.  The FAT
filesystem driver code is also BSD licensed, but the code license contains
one additional term.  This license can be found at
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Edk2-fat-driver,
and a copy is shown below (following the normal BSD license).

=== BSD license: START ===

Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
* Neither the name of the Intel Corporation nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

=== BSD license: END ===

=== FAT filesystem driver license: START ===

Copyright (c) 2004, Intel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
* Neither the name of Intel nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Additional terms:
In addition to the forgoing, redistribution and use of the code is
conditioned upon the FAT 32 File System Driver and all derivative
works thereof being used for and designed only to read and/or write
to a file system that is directly managed by an Extensible Firmware
Interface (EFI) implementation or by an emulator of an EFI
implementation.

=== FAT filesystem driver license: END ===
''')

def build(arch):
    args = (
        'OvmfPkg/build.sh',
        '-t', TOOLCHAIN,
        '-a', arch,
        '-b', 'RELEASE'
        )
    logname = 'build-%s.log' % arch
    build_log = open(logname, 'w')
    print 'Building OVMF for', arch, '(%s)' % logname, '...',
    sys.stdout.flush()
    p = subprocess.Popen(args=args, stdout=build_log, stderr=build_log)
    ret_code = p.wait()
    if ret_code == 0:
        print '[done]'
    else:
        print '[error 0x%x]' % ret_code
    return ret_code

def create_zip(arch):
    global build_info
    filename = 'OVMF-%s-r%d.zip' % (arch, revision)
    print 'Creating', filename, '...',
    sys.stdout.flush()
    if os.path.exists(filename):
        os.remove(filename)
    zipf = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED)

    zipf.writestr('BUILD_INFO', build_info)
    zipf.writestr('LICENSE', LICENSE)
    zipf.write(os.path.join('OvmfPkg', 'README'), 'README')
    FV_DIR = os.path.join(
        'Build',
        'Ovmf' + arch.title(),
        'RELEASE_' + TOOLCHAIN,
        'FV'
        )
    zipf.write(os.path.join(FV_DIR, 'OVMF.fd'), 'OVMF.fd')
    zipf.close()
    print '[done]'

build_info = gen_build_info()
build('IA32')
build('X64')
create_zip('IA32')
create_zip('X64')

<commit_msg>OvmfPkg/create-release.py: Support GCC44 through GCC47<commit_after>#!/usr/bin/python
#
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.

#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

import os
import re
import StringIO
import subprocess
import sys
import zipfile

is_unix = not sys.platform.startswith('win')

if not is_unix:
    print "This script currently only supports unix-like systems"
    sys.exit(-1)

if os.path.exists('OvmfPkgX64.dsc'):
    os.chdir('..')

if not os.path.exists(os.path.join('OvmfPkg', 'OvmfPkgX64.dsc')):
    print "OvmfPkg/OvmfPkgX64.dsc doesn't exist"
    sys.exit(-1)

def run_and_capture_output(args, checkExitCode = True):
    p = subprocess.Popen(args=args, stdout=subprocess.PIPE)
    stdout = p.stdout.read()
    ret_code = p.wait()
    if checkExitCode:
        assert ret_code == 0
    return stdout

gcc_version = run_and_capture_output(args=('gcc', '--version'))
gcc_re = re.compile(r'\s*\S+\s+\([^\)]+?\)\s+(\d+(?:\.\d+)*)(?:\s+.*)?')
mo = gcc_re.match(gcc_version)
if not mo:
    print "Unable to find GCC version"
    sys.exit(-1)
gcc_version = map(lambda n: int(n), mo.group(1).split('.'))

if 'TOOLCHAIN' in os.environ:
    TOOLCHAIN = os.environ['TOOLCHAIN']
else:
    assert(gcc_version[0] == 4)
    minor = max(4, min(7, gcc_version[1]))
    TOOLCHAIN = 'GCC4' + str(minor)

def git_svn_info():
    dir = os.getcwd()
    os.chdir('OvmfPkg')
    stdout = run_and_capture_output(args=('git', 'svn', 'info'))
    os.chdir(dir)
    return stdout

def svn_info():
    dir = os.getcwd()
    os.chdir('OvmfPkg')
    stdout = run_and_capture_output(args=('svn', 'info'))
    os.chdir(dir)
    return stdout

def get_svn_info_output():
    if os.path.exists(os.path.join('OvmfPkg', '.svn')):
        return svn_info()
    else:
        return git_svn_info()

def get_revision():
    buf = get_svn_info_output()
    revision_re = re.compile('^Revision\:\s*(\d+)$', re.MULTILINE)
    mo = revision_re.search(buf)
    if mo is not None:
        return int(mo.group(1))

revision = get_revision()

newline_re = re.compile(r'(\n|\r\n|\r(?!\n))', re.MULTILINE)
def to_dos_text(str):
    return newline_re.sub('\r\n', str)

def gen_build_info():
    distro = run_and_capture_output(args=('lsb_release', '-sd')).strip()

    machine = run_and_capture_output(args=('uname', '-m')).strip()

    gcc_version_str = '.'.join(map(lambda v: str(v), gcc_version))

    ld_version = run_and_capture_output(args=('ld', '--version'))
    ld_version = ld_version.split('\n')[0].split()[-1]

    iasl_version = run_and_capture_output(args=('iasl'), checkExitCode=False)
    iasl_version = filter(lambda s: s.find(' version ') >= 0, iasl_version.split('\n'))[0]
    iasl_version = iasl_version.split(' version ')[1].strip()

    sb = StringIO.StringIO()
    print >> sb, 'edk2:    ', 'r%d' % revision
    print >> sb, 'compiler: GCC', gcc_version_str, '(' + TOOLCHAIN + ')'
    print >> sb, 'binutils:', ld_version
    print >> sb, 'iasl:    ', iasl_version
    print >> sb, 'system:  ', distro, machine.replace('_', '-')
    return to_dos_text(sb.getvalue())

LICENSE = to_dos_text(
'''This OVMF binary release is built from source code licensed under
the BSD open source license.  The BSD license is documented at
http://opensource.org/licenses/bsd-license.php, and a copy is
shown below.

One sub-component of the OVMF project is a FAT filesystem driver.  The FAT
filesystem driver code is also BSD licensed, but the code license contains
one additional term.  This license can be found at
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Edk2-fat-driver,
and a copy is shown below (following the normal BSD license).

=== BSD license: START ===

Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
* Neither the name of the Intel Corporation nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

=== BSD license: END ===

=== FAT filesystem driver license: START ===

Copyright (c) 2004, Intel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.
* Neither the name of Intel nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Additional terms:
In addition to the forgoing, redistribution and use of the code is
conditioned upon the FAT 32 File System Driver and all derivative
works thereof being used for and designed only to read and/or write
to a file system that is directly managed by an Extensible Firmware
Interface (EFI) implementation or by an emulator of an EFI
implementation.

=== FAT filesystem driver license: END ===
''')

def build(arch):
    args = (
        'OvmfPkg/build.sh',
        '-t', TOOLCHAIN,
        '-a', arch,
        '-b', 'RELEASE'
        )
    logname = 'build-%s.log' % arch
    build_log = open(logname, 'w')
    print 'Building OVMF for', arch, '(%s)' % logname, '...',
    sys.stdout.flush()
    p = subprocess.Popen(args=args, stdout=build_log, stderr=build_log)
    ret_code = p.wait()
    if ret_code == 0:
        print '[done]'
    else:
        print '[error 0x%x]' % ret_code
    return ret_code

def create_zip(arch):
    global build_info
    filename = 'OVMF-%s-r%d.zip' % (arch, revision)
    print 'Creating', filename, '...',
    sys.stdout.flush()
    if os.path.exists(filename):
        os.remove(filename)
    zipf = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED)

    zipf.writestr('BUILD_INFO', build_info)
    zipf.writestr('LICENSE', LICENSE)
    zipf.write(os.path.join('OvmfPkg', 'README'), 'README')
    FV_DIR = os.path.join(
        'Build',
        'Ovmf' + arch.title(),
        'RELEASE_' + TOOLCHAIN,
        'FV'
        )
    zipf.write(os.path.join(FV_DIR, 'OVMF.fd'), 'OVMF.fd')
    zipf.close()
    print '[done]'

build_info = gen_build_info()
build('IA32')
build('X64')
create_zip('IA32')
create_zip('X64')

<|endoftext|>


<commit_before>"""Support for VeSync fans."""
import logging

from homeassistant.components.fan import (
    SPEED_HIGH,
    SPEED_LOW,
    SPEED_MEDIUM,
    SPEED_OFF,
    SUPPORT_SET_SPEED,
    FanEntity,
)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from .common import VeSyncDevice
from .const import DOMAIN, VS_DISCOVERY, VS_DISPATCHERS, VS_FANS

_LOGGER = logging.getLogger(__name__)

DEV_TYPE_TO_HA = {
    "LV-PUR131S": "fan",
}

SPEED_AUTO = "auto"
FAN_SPEEDS = [SPEED_AUTO, SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]

async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the VeSync fan platform."""

    async def async_discover(devices):
        """Add new devices to platform."""
        _async_setup_entities(devices, async_add_entities)

    disp = async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_FANS), async_discover)
    hass.data[DOMAIN][VS_DISPATCHERS].append(disp)

    _async_setup_entities(hass.data[DOMAIN][VS_FANS], async_add_entities)
    return True

@callback
def _async_setup_entities(devices, async_add_entities):
    """Check if device is online and add entity."""
    dev_list = []
    for dev in devices:
        if DEV_TYPE_TO_HA.get(dev.device_type) == "fan":
            dev_list.append(VeSyncFanHA(dev))
        else:
            _LOGGER.warning(
                "%s - Unknown device type - %s", dev.device_name, dev.device_type
            )
            continue

    async_add_entities(dev_list, update_before_add=True)

class VeSyncFanHA(VeSyncDevice, FanEntity):
    """Representation of a VeSync fan."""

    def __init__(self, fan):
        """Initialize the VeSync fan device."""
        super().__init__(fan)
        self.smartfan = fan

    @property
    def supported_features(self):
        """Flag supported features."""
        return SUPPORT_SET_SPEED

    @property
    def speed(self):
        """Return the current speed."""
        if self.smartfan.mode == SPEED_AUTO:
            return SPEED_AUTO
        if self.smartfan.mode == "manual":
            current_level = self.smartfan.fan_level
            if current_level is not None:
                return FAN_SPEEDS[current_level]
        return None

    @property
    def speed_list(self):
        """Get the list of available speeds."""
        return FAN_SPEEDS

    @property
    def unique_info(self):
        """Return the ID of this fan."""
        return self.smartfan.uuid

    @property
    def device_state_attributes(self):
        """Return the state attributes of the fan."""
        return {
            "mode": self.smartfan.mode,
            "active_time": self.smartfan.active_time,
            "filter_life": self.smartfan.filter_life,
            "air_quality": self.smartfan.air_quality,
            "screen_status": self.smartfan.screen_status,
        }

    def set_speed(self, speed):
        """Set the speed of the device."""
        if not self.smartfan.is_on:
            self.smartfan.turn_on()

        if speed is None or speed == SPEED_AUTO:
            self.smartfan.auto_mode()
        else:
            self.smartfan.manual_mode()
            self.smartfan.change_fan_speed(FAN_SPEEDS.index(speed))

    def turn_on(self, speed: str = None, **kwargs) -> None:
        """Turn the device on."""
        self.smartfan.turn_on()
        self.set_speed(speed)
<commit_msg>Remove auto from the fan speed modes for VeSync (#40559)<commit_after>"""Support for VeSync fans."""
import logging

from homeassistant.components.fan import (
    SPEED_HIGH,
    SPEED_LOW,
    SPEED_MEDIUM,
    SPEED_OFF,
    SUPPORT_SET_SPEED,
    FanEntity,
)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from .common import VeSyncDevice
from .const import DOMAIN, VS_DISCOVERY, VS_DISPATCHERS, VS_FANS

_LOGGER = logging.getLogger(__name__)

DEV_TYPE_TO_HA = {
    "LV-PUR131S": "fan",
}

FAN_SPEEDS = [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
FAN_MODE_AUTO = "auto"

async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the VeSync fan platform."""

    async def async_discover(devices):
        """Add new devices to platform."""
        _async_setup_entities(devices, async_add_entities)

    disp = async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_FANS), async_discover)
    hass.data[DOMAIN][VS_DISPATCHERS].append(disp)

    _async_setup_entities(hass.data[DOMAIN][VS_FANS], async_add_entities)

@callback
def _async_setup_entities(devices, async_add_entities):
    """Check if device is online and add entity."""
    dev_list = []
    for dev in devices:
        if DEV_TYPE_TO_HA.get(dev.device_type) == "fan":
            dev_list.append(VeSyncFanHA(dev))
        else:
            _LOGGER.warning(
                "%s - Unknown device type - %s", dev.device_name, dev.device_type
            )
            continue

    async_add_entities(dev_list, update_before_add=True)

class VeSyncFanHA(VeSyncDevice, FanEntity):
    """Representation of a VeSync fan."""

    def __init__(self, fan):
        """Initialize the VeSync fan device."""
        super().__init__(fan)
        self.smartfan = fan

    @property
    def supported_features(self):
        """Flag supported features."""
        return SUPPORT_SET_SPEED

    @property
    def speed(self):
        """Return the current speed."""
        if self.smartfan.mode == FAN_MODE_AUTO:
            return None
        if self.smartfan.mode == "manual":
            current_level = self.smartfan.fan_level
            if current_level is not None:
                return FAN_SPEEDS[current_level]
        return None

    @property
    def speed_list(self):
        """Get the list of available speeds."""
        return FAN_SPEEDS

    @property
    def unique_info(self):
        """Return the ID of this fan."""
        return self.smartfan.uuid

    @property
    def device_state_attributes(self):
        """Return the state attributes of the fan."""
        return {
            "mode": self.smartfan.mode,
            "active_time": self.smartfan.active_time,
            "filter_life": self.smartfan.filter_life,
            "air_quality": self.smartfan.air_quality,
            "screen_status": self.smartfan.screen_status,
        }

    def set_speed(self, speed):
        """Set the speed of the device."""
        if not self.smartfan.is_on:
            self.smartfan.turn_on()

        self.smartfan.manual_mode()
        self.smartfan.change_fan_speed(FAN_SPEEDS.index(speed))

    def turn_on(self, speed: str = None, **kwargs) -> None:
        """Turn the device on."""
        self.smartfan.turn_on()
        self.set_speed(speed)
<|endoftext|>


<commit_before># -*- coding: us-ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#

# Vision for data structure to be stored in cache:

# games: {
#     game1: {
#         players: {
#             player1: {
#                 hand: [...],
#                 wins: int,
#                 submitted = current submitted card,
#             },
#             player2 {...},
#             ...
#         },
#         current_black_card = None|int,
#         submissions = [dict of player submissions for the round],
#         round: int,
#         card_czar = 'player1',  # int index into 'players'
#         black_deck = [],
#         white_deck = [],
#     },
#     game2 {...},
#     ...
# }

# Contract between LobbyView and PlayerView:
#
# LobbyView will give PlayerView a named player and a game stored in cache.
# PlayerView will return to LobbyView any request that does not have those things.
# On the cache, 'players' will hav a mapping of ids to players.

import os
import json
import random
import hashlib
import urllib

from django.conf import settings
from django.views.generic import FormView, TemplateView
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.core.cache import cache
from forms import PlayerForm, GameForm, CzarForm
from game import Game
from pprint import pprint
import log
import uuid

# Grab data from the cards json and set global, unaltered decks.
with open(os.path.join(settings.PROJECT_ROOT, 'data/data.json')) as data:
    cards = json.loads(data.read())
    black_cards = cards['black_cards']
    white_cards = cards['white_cards']
    blank_marker = cards['blank']

def gravatar_robohash_url(email, size=50):
    """Generate url for RoboHash image  (gravatar first then robohash)"""
    text_to_hash = hashlib.md5(email.lower()).hexdigest()
    robohash_url = "http://robohash.org/%s?size=%dx%d&gravatar=hashed" % (text_to_hash, size, size)
    return robohash_url

def gravatar_url(email, size=50, default='monsterid'):
    """Generate url for Gravatar image
    email - email address
    default = default_image_url or default hash type
    """
    gravatar_url = "http://www.gravatar.com/avatar/" + hashlib.md5(email.lower()).hexdigest() + "?"
    if default:
        gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
    else:
        gravatar_url += urllib.urlencode({'s':str(size)})
    return gravatar_url

avatar_url = gravatar_robohash_url
avatar_url = gravatar_url

class PlayerView(FormView):

    template_name = 'player.html'
    form_class = PlayerForm

    def __init__(self, *args, **kwargs):
        super(PlayerView, self).__init__(*args, **kwargs)

    def dispatch(self, request, *args, **kwargs):
        # Setup for game and player
        if not self.request.session.get('game_name') or not self.request.session.get('player_name'):
            return redirect(reverse('lobby-view'))

        self.player_id = self.request.session.get('player_id')

        players = cache.get('players', {})
        player = players.get(self.player_id, {})
        if not player:
            # del maybe overkill...
            del self.request.session['player_id']
            if self.request.session.get('player_name'):
                del self.request.session['player_name']
            if self.request.session.get('game_name'):
                del self.request.session['game_name']
            return redirect(reverse('lobby-view'))

        self.game_name = self.request.session.get('game_name')
        self.player_name = self.request.session.get('player_name')

        try:
            self.game_data = cache.get('games').get(self.game_name)
        except AttributeError:
            return redirect(reverse('lobby-view'))
        if not self.game_data:
            return redirect(reverse('lobby-view'))
        self.is_card_czar = self.game_data['card_czar'] == self.player_id
        log.logger.debug('id %r name %r game %r', self.player_id, self.player_name, self.game_name)

        self.player_data = self.game_data['players'].get(self.player_name)
        # Deal hand if player doesn't have one.
        if not self.player_data['hand']:
            self.player_data['hand'] = [
                self.game_data['white_deck'].pop() for x in xrange(10)
            ]

        # Deal black card if game doesn't have one.
        if self.game_data['current_black_card'] is None:
            self.game_data['current_black_card'] = self.deal_black_card()
        self.write_state()

        if self.is_card_czar:
            self.form_class = CzarForm
        return super(PlayerView, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('player-view')

    def get_context_data(self, *args, **kwargs):

        context = super(PlayerView, self).get_context_data(*args, **kwargs)
        context['players'] = self.game_data['players']
        last_round_winner = self.game_data.get('last_round_winner', '')
        context['last_round_winner'] = last_round_winner
        if last_round_winner:
            context['last_round_winner_avatar'] = self.game_data['players'][last_round_winner]['player_avatar']
        num_blanks = self.black_card.count(blank_marker)
        context['black_card'] = self.black_card.replace(blank_marker, '______')
        context['player_name'] = self.player_name
        context['player_avatar'] = self.game_data['players'][self.player_name]['player_avatar']
        context['game_name'] = self.game_name
        context['show_form'] = self.can_show_form()
        # Display filled-in answer if player has submitted.
        if self.game_data['submissions'] and not self.is_card_czar:
            player_submission = self.game_data['submissions'].get(self.player_id)
            context['filled_in_question'] = self.replace_blanks(player_submission)
        context['action'] = reverse('player-view')
        return context

    def get_form_kwargs(self):
        self.black_card = black_cards[self.game_data['current_black_card']]
        kwargs = super(PlayerView, self).get_form_kwargs()
        if self.is_card_czar:
            kwargs['cards'] = [(player_id, self.replace_blanks(self.game_data['submissions'][player_id])) for player_id in self.game_data['submissions']]
        else:
            kwargs['blanks'] = black_cards[self.game_data['current_black_card']].count(blank_marker) or 1
            kwargs['cards'] = tuple(
                (card, white_cards[card]) for card in self.player_data['hand']
            )
        return kwargs

    def form_valid(self, form):
        if self.is_card_czar:
            players = cache.get('players')
            winner = form.cleaned_data['card_selection']
            log.logger.debug(winner)
            winner_name = players[uuid.UUID(winner)].get('name')
            self.reset(winner_name, uuid.UUID(winner))

        else:
            submitted = form.cleaned_data['card_selection']
            # The form returns unicode strings. We want ints in our list.
            self.game_data['submissions'][self.player_id] = [int(card) for card in submitted]
            for card in self.game_data['submissions'][self.player_id]:
                self.player_data['hand'].remove(card)
            log.logger.debug('%r', form.cleaned_data['card_selection'])
        self.write_state()
        log.logger.debug(cache.get('games'))
        return super(PlayerView, self).form_valid(form)

    def write_state(self):
        self.request.session['player_name'] = self.player_name
        self.request.session['game_name'] = self.game_name
        self.game_data['players'][self.player_name] = self.player_data
        games_dict = cache.get('games')
        games_dict[self.game_name] = self.game_data
        cache.set('games', games_dict)

    def can_show_form(self):
        flag = False
        # import pdb; pdb.set_trace()
        if self.game_data['card_czar'] == self.player_id:
            if not self.game_data['submissions']:
                flag = False
            elif len(self.game_data['submissions']) == len(self.game_data['players']) - 1:
                flag = True
            else:
                flag = False
        else:
            if self.player_id in self.game_data['submissions']:
                flag = False
            else:
                flag = True
        return flag

    def replace_blanks(self, white_card_num_list):
        card_text = self.black_card
        num_blanks = self.black_card.count(blank_marker)
        # assume num_blanks count is valid and len(white_card_num_list) == num_blanks
        if num_blanks == 0:
            card_num = white_card_num_list[0]
            white_text = white_cards[card_num]
            white_text = '' + white_text + ''
            card_text = card_text + ' ' + white_text
        else:
            for card_num in white_card_num_list:
                white_text = white_cards[card_num]
                white_text = white_text.rstrip('.')
                """We can't change the case of the first letter in case
                it is a real name :-( We'd need to consult a word list,
                to make that decision which is way too much effort at
                the moment."""
                white_text = '' + white_text + ''
                card_text = card_text.replace(blank_marker, white_text, 1)
        return card_text

    def reset(self, winner=None, winner_id=None):
        self.game_data['submissions'] = {}
        num_blanks = black_cards[self.game_data['current_black_card']].count(blank_marker)
        self.game_data['current_black_card'] = self.deal_black_card()
        self.game_data['players'][winner]['wins'] += 1
        self.game_data['card_czar'] = winner_id
        self.game_data['round'] += 1
        self.game_data['last_round_winner'] = winner

        if num_blanks == 0:
            num_blanks = 1
        for _ in xrange(num_blanks):
            for player_name in self.game_data['players']:
                if player_name != self.player_name:
                    self.game_data['players'][player_name]['hand'].append(self.game_data['white_deck'].pop())

    def deal_black_card(self):
        black_card = self.game_data['black_deck'].pop()
        if len(self.game_data['black_deck']) == 0:
            shuffled_black = range(len(black_cards))
            random.shuffle(shuffled_black)
            self.game_data['black_deck'] = shuffled_black
        return black_card

class LobbyView(FormView):

    template_name = 'lobby.html'
    form_class = GameForm

    def __init__(self, *args, **kwargs):
        self.game_list = cache.get('games')

    # def dispatch(self, request, *args, **kwargs):
        # return super(PlayerView, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('player-view')

    def get_context_data(self, *args, **kwargs):
        context = super(LobbyView, self).get_context_data(*args, **kwargs)
        context['show_form'] = True
        self.player_id = self.request.session.get('player_id')
        if not self.player_id:
            self.player_id = uuid.uuid1()
            self.request.session['player_id'] = self.player_id
            # del maybe overkill...
            if self.request.session.get('player_name'):
                del self.request.session['player_name']
            if self.request.session.get('game_name'):
                del self.request.session['game_name']

        return context

    def get_form_kwargs(self):
        kwargs = super(LobbyView, self).get_form_kwargs()
        if self.game_list:
            kwargs['game_list'] = [(game, game) for game in self.game_list.keys()]
        return kwargs

    def form_valid(self, form):
        self.player_id = self.request.session.get('player_id')
        player_name = form.cleaned_data['player_name']

        existing_game = True
        # Set the game properties in the cache
        game_name = form.cleaned_data['new_game']
        games = cache.get('games', {})
        if game_name:
            # Attempting to create a new game
            existing_game = games.get(game_name)
            if not existing_game:
                # really a new game
                new_game = self.create_game()
                new_game['players'][player_name] = self.create_player(player_name)
                new_game['card_czar'] = self.player_id
                games[form.cleaned_data['new_game']] = new_game
        if existing_game:
            if not game_name:
                game_name = form.cleaned_data.get('game_list')
            log.logger.debug('existing_game %r', (game_name, player_name,))
            if not games[game_name]['players'].get(player_name):
                games[game_name]['players'][player_name] = self.create_player(player_name)
            else:
                # FIXME
                raise NotImplementedError('joining with player names alreaady in same game causes problems')
        cache.set('games', games)

        # Set the player properties in the cache
        players = cache.get('players', {})
        player = players.get(self.player_id, {})
        player['name'] = player_name
        player['game'] = game_name
        players[self.player_id] = player
        cache.set('players', players)

        log.logger.debug(cache.get('players'))
        self.request.session['game_name'] = game_name  # TODO check these should be removed, looks like we still rely on cookie contents for user/game name
        self.request.session['player_name'] = player_name

        return super(LobbyView, self).form_valid(form)

    def create_game(self):
        log.logger.debug("New Game called")
        """Create shuffled decks
        uses built in random, it may be better to plug-in a better
        random init routine and/also consider using
        https://pypi.python.org/pypi/shuffle/

        Also take a look at http://code.google.com/p/gcge/
        """
        shuffled_white = range(len(white_cards))
        random.shuffle(shuffled_white)
        shuffled_black = range(len(black_cards))
        random.shuffle(shuffled_black)

        # Basic data object for a game. Eventually, this will be saved in cache.
        return {
            'players': {},
            'current_black_card': None,  # get a new one my shuffled_black.pop()
            'submissions': {},
            'round': 0,
            'card_czar': '',
            'white_deck': shuffled_white,
            'black_deck': shuffled_black,
            'mode': 'submitting',
        }

    def create_player(self, player_name):
        log.logger.debug("new player called")
        # Basic data obj for player. Eventually, this will be saved in cache.
        return {
            'hand': [],
            'wins': 0,
            'player_avatar': avatar_url(player_name),
        }
<commit_msg>remove player/game name from session.<commit_after># -*- coding: us-ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#

# Vision for data structure to be stored in cache:

# games: {
#     game1: {
#         players: {
#             player1: {
#                 hand: [...],
#                 wins: int,
#                 submitted = current submitted card,
#             },
#             player2 {...},
#             ...
#         },
#         current_black_card = None|int,
#         submissions = [dict of player submissions for the round],
#         round: int,
#         card_czar = 'player1',  # int index into 'players'
#         black_deck = [],
#         white_deck = [],
#     },
#     game2 {...},
#     ...
# }

# Contract between LobbyView and PlayerView:
#
# LobbyView will give PlayerView a named player and a game stored in cache.
# PlayerView will return to LobbyView any request that does not have those things.
# On the cache, 'players' will hav a mapping of ids to players.

import os
import json
import random
import hashlib
import urllib

from django.conf import settings
from django.views.generic import FormView, TemplateView
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.core.cache import cache
from forms import PlayerForm, GameForm, CzarForm
from game import Game
from pprint import pprint
import log
import uuid

# Grab data from the cards json and set global, unaltered decks.
with open(os.path.join(settings.PROJECT_ROOT, 'data/data.json')) as data:
    cards = json.loads(data.read())
    black_cards = cards['black_cards']
    white_cards = cards['white_cards']
    blank_marker = cards['blank']

def gravatar_robohash_url(email, size=50):
    """Generate url for RoboHash image  (gravatar first then robohash)"""
    text_to_hash = hashlib.md5(email.lower()).hexdigest()
    robohash_url = "http://robohash.org/%s?size=%dx%d&gravatar=hashed" % (text_to_hash, size, size)
    return robohash_url

def gravatar_url(email, size=50, default='monsterid'):
    """Generate url for Gravatar image
    email - email address
    default = default_image_url or default hash type
    """
    gravatar_url = "http://www.gravatar.com/avatar/" + hashlib.md5(email.lower()).hexdigest() + "?"
    if default:
        gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
    else:
        gravatar_url += urllib.urlencode({'s':str(size)})
    return gravatar_url

avatar_url = gravatar_robohash_url
avatar_url = gravatar_url

class PlayerView(FormView):

    template_name = 'player.html'
    form_class = PlayerForm

    def __init__(self, *args, **kwargs):
        super(PlayerView, self).__init__(*args, **kwargs)

    def dispatch(self, request, *args, **kwargs):
        # Setup for game and player

        self.player_id = self.request.session.get('player_id')

        players = cache.get('players', {})
        player = players.get(self.player_id, {})
        if not player:
            return redirect(reverse('lobby-view'))

        self.game_name = player['game']
        self.player_name = player['name']

        try:
            self.game_data = cache.get('games').get(self.game_name)
        except AttributeError:
            return redirect(reverse('lobby-view'))
        if not self.game_data:
            return redirect(reverse('lobby-view'))
        self.is_card_czar = self.game_data['card_czar'] == self.player_id
        log.logger.debug('id %r name %r game %r', self.player_id, self.player_name, self.game_name)

        self.player_data = self.game_data['players'].get(self.player_name)
        # Deal hand if player doesn't have one.
        if not self.player_data['hand']:
            self.player_data['hand'] = [
                self.game_data['white_deck'].pop() for x in xrange(10)
            ]

        # Deal black card if game doesn't have one.
        if self.game_data['current_black_card'] is None:
            self.game_data['current_black_card'] = self.deal_black_card()
        self.write_state()

        if self.is_card_czar:
            self.form_class = CzarForm
        return super(PlayerView, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('player-view')

    def get_context_data(self, *args, **kwargs):

        context = super(PlayerView, self).get_context_data(*args, **kwargs)
        context['players'] = self.game_data['players']
        last_round_winner = self.game_data.get('last_round_winner', '')
        context['last_round_winner'] = last_round_winner
        if last_round_winner:
            context['last_round_winner_avatar'] = self.game_data['players'][last_round_winner]['player_avatar']
        num_blanks = self.black_card.count(blank_marker)
        context['black_card'] = self.black_card.replace(blank_marker, '______')
        context['player_name'] = self.player_name
        context['player_avatar'] = self.game_data['players'][self.player_name]['player_avatar']
        context['game_name'] = self.game_name
        context['show_form'] = self.can_show_form()
        # Display filled-in answer if player has submitted.
        if self.game_data['submissions'] and not self.is_card_czar:
            player_submission = self.game_data['submissions'].get(self.player_id)
            context['filled_in_question'] = self.replace_blanks(player_submission)
        context['action'] = reverse('player-view')
        return context

    def get_form_kwargs(self):
        self.black_card = black_cards[self.game_data['current_black_card']]
        kwargs = super(PlayerView, self).get_form_kwargs()
        if self.is_card_czar:
            kwargs['cards'] = [(player_id, self.replace_blanks(self.game_data['submissions'][player_id])) for player_id in self.game_data['submissions']]
        else:
            kwargs['blanks'] = black_cards[self.game_data['current_black_card']].count(blank_marker) or 1
            kwargs['cards'] = tuple(
                (card, white_cards[card]) for card in self.player_data['hand']
            )
        return kwargs

    def form_valid(self, form):
        if self.is_card_czar:
            players = cache.get('players')
            winner = form.cleaned_data['card_selection']
            log.logger.debug(winner)
            winner_name = players[uuid.UUID(winner)].get('name')
            self.reset(winner_name, uuid.UUID(winner))

        else:
            submitted = form.cleaned_data['card_selection']
            # The form returns unicode strings. We want ints in our list.
            self.game_data['submissions'][self.player_id] = [int(card) for card in submitted]
            for card in self.game_data['submissions'][self.player_id]:
                self.player_data['hand'].remove(card)
            log.logger.debug('%r', form.cleaned_data['card_selection'])
        self.write_state()
        log.logger.debug(cache.get('games'))
        return super(PlayerView, self).form_valid(form)

    def write_state(self):
        self.game_data['players'][self.player_name] = self.player_data
        games_dict = cache.get('games')
        games_dict[self.game_name] = self.game_data
        cache.set('games', games_dict)

    def can_show_form(self):
        flag = False
        # import pdb; pdb.set_trace()
        if self.game_data['card_czar'] == self.player_id:
            if not self.game_data['submissions']:
                flag = False
            elif len(self.game_data['submissions']) == len(self.game_data['players']) - 1:
                flag = True
            else:
                flag = False
        else:
            if self.player_id in self.game_data['submissions']:
                flag = False
            else:
                flag = True
        return flag

    def replace_blanks(self, white_card_num_list):
        card_text = self.black_card
        num_blanks = self.black_card.count(blank_marker)
        # assume num_blanks count is valid and len(white_card_num_list) == num_blanks
        if num_blanks == 0:
            card_num = white_card_num_list[0]
            white_text = white_cards[card_num]
            white_text = '' + white_text + ''
            card_text = card_text + ' ' + white_text
        else:
            for card_num in white_card_num_list:
                white_text = white_cards[card_num]
                white_text = white_text.rstrip('.')
                """We can't change the case of the first letter in case
                it is a real name :-( We'd need to consult a word list,
                to make that decision which is way too much effort at
                the moment."""
                white_text = '' + white_text + ''
                card_text = card_text.replace(blank_marker, white_text, 1)
        return card_text

    def reset(self, winner=None, winner_id=None):
        self.game_data['submissions'] = {}
        num_blanks = black_cards[self.game_data['current_black_card']].count(blank_marker)
        self.game_data['current_black_card'] = self.deal_black_card()
        self.game_data['players'][winner]['wins'] += 1
        self.game_data['card_czar'] = winner_id
        self.game_data['round'] += 1
        self.game_data['last_round_winner'] = winner

        if num_blanks == 0:
            num_blanks = 1
        for _ in xrange(num_blanks):
            for player_name in self.game_data['players']:
                if player_name != self.player_name:
                    self.game_data['players'][player_name]['hand'].append(self.game_data['white_deck'].pop())

    def deal_black_card(self):
        black_card = self.game_data['black_deck'].pop()
        if len(self.game_data['black_deck']) == 0:
            shuffled_black = range(len(black_cards))
            random.shuffle(shuffled_black)
            self.game_data['black_deck'] = shuffled_black
        return black_card

class LobbyView(FormView):

    template_name = 'lobby.html'
    form_class = GameForm

    def __init__(self, *args, **kwargs):
        self.game_list = cache.get('games')

    # def dispatch(self, request, *args, **kwargs):
        # return super(PlayerView, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('player-view')

    def get_context_data(self, *args, **kwargs):
        context = super(LobbyView, self).get_context_data(*args, **kwargs)
        context['show_form'] = True
        self.player_id = self.request.session.get('player_id')
        if not self.player_id:
            self.player_id = uuid.uuid1()
            self.request.session['player_id'] = self.player_id

        return context

    def get_form_kwargs(self):
        kwargs = super(LobbyView, self).get_form_kwargs()
        if self.game_list:
            kwargs['game_list'] = [(game, game) for game in self.game_list.keys()]
        return kwargs

    def form_valid(self, form):
        self.player_id = self.request.session.get('player_id')
        player_name = form.cleaned_data['player_name']

        existing_game = True
        # Set the game properties in the cache
        game_name = form.cleaned_data['new_game']
        games = cache.get('games', {})
        if game_name:
            # Attempting to create a new game
            existing_game = games.get(game_name)
            if not existing_game:
                # really a new game
                new_game = self.create_game()
                new_game['players'][player_name] = self.create_player(player_name)
                new_game['card_czar'] = self.player_id
                games[form.cleaned_data['new_game']] = new_game
        if existing_game:
            if not game_name:
                game_name = form.cleaned_data.get('game_list')
            log.logger.debug('existing_game %r', (game_name, player_name,))
            if not games[game_name]['players'].get(player_name):
                games[game_name]['players'][player_name] = self.create_player(player_name)
            else:
                # FIXME
                raise NotImplementedError('joining with player names alreaady in same game causes problems')
        cache.set('games', games)

        # Set the player properties in the cache
        players = cache.get('players', {})
        player = players.get(self.player_id, {})
        player['name'] = player_name
        player['game'] = game_name
        players[self.player_id] = player
        cache.set('players', players)

        log.logger.debug(cache.get('players'))

        return super(LobbyView, self).form_valid(form)

    def create_game(self):
        log.logger.debug("New Game called")
        """Create shuffled decks
        uses built in random, it may be better to plug-in a better
        random init routine and/also consider using
        https://pypi.python.org/pypi/shuffle/

        Also take a look at http://code.google.com/p/gcge/
        """
        shuffled_white = range(len(white_cards))
        random.shuffle(shuffled_white)
        shuffled_black = range(len(black_cards))
        random.shuffle(shuffled_black)

        # Basic data object for a game. Eventually, this will be saved in cache.
        return {
            'players': {},
            'current_black_card': None,  # get a new one my shuffled_black.pop()
            'submissions': {},
            'round': 0,
            'card_czar': '',
            'white_deck': shuffled_white,
            'black_deck': shuffled_black,
            'mode': 'submitting',
        }

    def create_player(self, player_name):
        log.logger.debug("new player called")
        # Basic data obj for player. Eventually, this will be saved in cache.
        return {
            'hand': [],
            'wins': 0,
            'player_avatar': avatar_url(player_name),
        }
<|endoftext|>


<commit_before>from content_extraction import entry2text
from InferSent.encoder import models as im
from joblib import Memory
from nltk.data import load as nltk_load
from numpy import resize
import os
import re
import torch

_sent_detector = nltk_load('tokenizers/punkt/english.pickle')

# alternate infersent load method based on
# https://stackoverflow.com/questions/42703500/best-way-to-save-a-trained-model-in-pytorch
# as chdir doesn't work in flask
_config = dict(
    bsize=64,
    word_emb_dim=300,
    enc_lstm_dim=2048,
    pool_type='max',
    dpout_model=0.0,
    use_cuda=False)
# copied from loaded object
_infersent = im.BLSTMEncoder(_config)
_infersent.load_state_dict(
    torch.load(
        'InferSent/encoder/infersent.allnli.state.pickle',
        map_location=lambda storage, loc: storage))
# saved with torch.save(
# _infersent.state_dict(), "InferSent/encoder/infersent.allnli.state.pickle")
_infersent.set_glove_path('InferSent/dataset/GloVe/glove.840B.300d.txt')
_infersent.build_vocab_k_words(K=1)

_memory = Memory(cachedir="feature-cache", verbose=1, bytes_limit=10**9)

# @_memory.cache(ignore=["entry"])
def entry2mat(entry):
    return _text2mat(entry2text(entry))

def text2sentences(text, max_sentences=100):
    return _sent_detector.tokenize(text.strip())[:max_sentences]

@_memory.cache
def _text2mat(text):
    sentences = text2sentences(text)  # limit to cap latency
    _infersent.update_vocab(sentences, tokenize=True)
    if sentences:
        return _infersent.encode(sentences, tokenize=True)
    else:
        raise FailedExtraction
<commit_msg>getting ambitious for long form content<commit_after>from content_extraction import entry2text
from InferSent.encoder import models as im
from joblib import Memory
from nltk.data import load as nltk_load
from numpy import resize
import os
import re
import torch

_sent_detector = nltk_load('tokenizers/punkt/english.pickle')

# alternate infersent load method based on
# https://stackoverflow.com/questions/42703500/best-way-to-save-a-trained-model-in-pytorch
# as chdir doesn't work in flask
_config = dict(
    bsize=64,
    word_emb_dim=300,
    enc_lstm_dim=2048,
    pool_type='max',
    dpout_model=0.0,
    use_cuda=False)
# copied from loaded object
_infersent = im.BLSTMEncoder(_config)
_infersent.load_state_dict(
    torch.load(
        'InferSent/encoder/infersent.allnli.state.pickle',
        map_location=lambda storage, loc: storage))
# saved with torch.save(
# _infersent.state_dict(), "InferSent/encoder/infersent.allnli.state.pickle")
_infersent.set_glove_path('InferSent/dataset/GloVe/glove.840B.300d.txt')
_infersent.build_vocab_k_words(K=1)

_memory = Memory(cachedir="feature-cache", verbose=1, bytes_limit=10**9)

# @_memory.cache(ignore=["entry"])
def entry2mat(entry):
    return _text2mat(entry2text(entry))

def text2sentences(text, max_sentences=300):  # limit to cap latency
    return _sent_detector.tokenize(text.strip())[:max_sentences]

@_memory.cache
def _text2mat(text):
    sentences = text2sentences(text)
    _infersent.update_vocab(sentences, tokenize=True)
    if sentences:
        return _infersent.encode(sentences, tokenize=True)
    else:
        raise FailedExtraction
<|endoftext|>


<commit_before>#!/usr/bin/env python

import sqlite3
import re
from feature_tbl_entry import FeatureTblEntry

def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

# Takes blast hit and returns it as a CSV of key=value
def parse_blast_hit_gene(blast_hit):
    if len(blast_hit) == 0 or blast_hit == '.':
        return ''

    attributes = ''
    parts = blast_hit.split('`')

    part1_split = parts[0].split('|')
    attributes += "gene="+re.sub(r'_(.*)$', '', part1_split[2])

    return attributes

# Takes blast hit and returns it as a CSV of key=value
def parse_blast_hit_cds(blast_hit):
    if len(blast_hit) == 0 or blast_hit == '.':
        return 'product=hypothetical protein'

    attributes = ''
    parts = blast_hit.split('`')

    matchObj = re.search( r'RecName: Full=([^;]*)', blast_hit)
    if matchObj:
        attributes += "product="+matchObj.group(1)
    else:
        attributes += "product=hypothetical protein"

    return attributes

# Takes gene ontology and returns it as a CSV of key=value
def parse_gene_ontology(gene_ontology):
    if len(gene_ontology) == 0 or gene_ontology == '.':
        return ''

    attributes = ''
    elements = gene_ontology.split('`')
    for element in elements:
        if len(attributes) > 0:
            attributes += ','

	element = replace(element, ',', '')
        vals = element.split('^')
        if vals[1] == 'molecular_function':
            attributes += 'go_function='
        elif vals[1] == 'cellular_component':
            attributes += 'go_component='
        elif vals[1] == 'biological_process':
            attributes += 'go_process='
        attributes += vals[2]+'|'+vals[0][3:]+'||IEA'
    return attributes

def reverse_indices(row):
    tmp = row[0]
    row[0] = row[1]
    row[1] = tmp
    return row

class FeatureTblWriter:

    def write_to_file(self, db_conn, fileName):
        db_conn.create_function('regexp', 2, regexp)

        db_cur = db_conn.cursor()

        with open(fileName, 'w') as f:
            ## Stupid first line??
            f.write('>Feature SeqId\n')

            # Get the sequence ids
            db_cur.execute('SELECT * FROM fasta')

            i = 0
            for seq in db_cur.fetchall():
                i += 1
                if i%100 == 0:
                    print(i)

                f.write('>Feature '+seq[0]+'\n')
                f.write('1\t'+str(len(seq[1]))+'\tREFERENCE\n')
                f.write('\t\t\tPBARC\t12345\n')

                # Create the temporary table
                # db_cur.execute('CREATE TABLE tmp_cur_seq(id TEXT PRIMARY KEY, seq_id TEXT, type TEXT, start INT, stop INT, name TEXT, parent TEXT)')

                # TODO: Match columns up with gff columns (i.e. strand isn't last in gff table)
                magic_query = "CREATE TEMP TABLE tmp_cur_seq AS SELECT id, seq_id, type, start, stop, name, parent, strand, phase FROM gff WHERE seq_id=?"

                # Store temporary table of all info pertaining to this sequence
                db_cur.execute(magic_query, [seq[0]])

                # Grab the genes on this sequence
                db_cur.execute('SELECT * FROM tmp_cur_seq WHERE type="gene"')
                genes = db_cur.fetchall()

                for gene in genes:
                    # Whether or not the gene is good to write
                    gene_good = true
                    exon_entries = []
                    cds_entries = []

                    # Find a trinotate entry to give us the gene id for this gene
                    db_cur.execute('SELECT top_blast_hit FROM trinotate WHERE prot_id REGEXP ? LIMIT 1', [gene[5]])
                    trinotate = db_cur.fetchone()

                    # Write the gene
                    gene_entry = FeatureTblEntry()
                    gene_entry.set_type('gene')
                    gene_entry.set_strand(gene[7])
                    gene_entry.set_partial_info(True, True)
                    if gene[8] != '.':
                        gene_entry.set_phase(int(gene[8]))
                    gene_entry.add_coordinates(gene[3], gene[4])
                    gene_ann = 'locus_tag='+gene[5]
                    if trinotate:
                        gene_ann += ','+parse_blast_hit_gene(trinotate[0])
                    for annot in gene_ann.split(','):
                        key_val = annot.split('=')
                        if len(key_val) == 2:
                            gene_entry.add_annotation(key_val[0], key_val[1])
                    if gene_entry.get_total_length() < 150:
                        gene_good = false

                    # Grab the mRNAs on this sequence
                    db_cur.execute('SELECT * FROM tmp_cur_seq WHERE type="mRNA" AND parent=?', [gene[0]])
                    rnas = db_cur.fetchall()

                    for rna in rnas:
                        # Grab the trinotate entry
                        trinotate = None
                        if re.match( r'maker', rna[5]):
                            db_cur.execute('SELECT * FROM trinotate WHERE prot_id=? LIMIT 1', [rna[5]])
                        else:
                            stripped_prot_id = re.sub(r'\.(\d*)', '', rna[5])
                            db_cur.execute('SELECT * FROM trinotate WHERE prot_id=? LIMIT 1', [stripped_prot_id])
                            trinotate = db_cur.fetchone()

                        if not trinotate:
                            print("Couldn't find annotation for "+rna[5]+". Skipping...")
                            continue

                        # Get whether the sequence has start and stop codons
                        db_cur.execute('SELECT EXISTS(SELECT type, name FROM tmp_cur_seq WHERE type="start_codon" AND parent=? LIMIT 1)', [rna[0]])
                        has_start = db_cur.fetchone()[0]
                        db_cur.execute('SELECT EXISTS(SELECT type, name FROM tmp_cur_seq WHERE type="stop_codon" AND parent=? LIMIT 1)', [rna[0]])
                        has_stop = db_cur.fetchone()[0]

                        # Annotation stuff
                        split_prot_id = rna[5].split('_')
                        cds_exon_ann_base = ''
                        cds_exon_ann_base += 'protein_id='+'gnl|PBARC|'+rna[5]+','
                        cds_exon_ann_base += 'transcript_id='+'gnl|PBARC|'+split_prot_id[0]+'_mrna'+split_prot_id[1]+','
                        cds_exon_ann_base += parse_blast_hit_cds(trinotate[3])

                        ##### EXON
                        # Grab all exons under this mRNA
                        db_cur.execute('SELECT start, stop, strand, phase FROM tmp_cur_seq WHERE type="exon" AND parent=?', [rna[0]])
                        exons = db_cur.fetchall()

                        if len(exons) > 0:
                            entry = FeatureTblEntry()
                            entry.set_type('mRNA') # Exons are actually mRNA?
                            entry.set_partial_info(has_start, has_stop)
                            entry.set_strand(exons[0][2])
                            if exons[0][3] != '.':
                                entry.set_phase(int(exons[0][3]))
                            [entry.add_coordinates(exon[0], exon[1]) for exon in exons]
                            exon_ann = cds_exon_ann_base
                            for annot in exon_ann.split(','):
                                key_val = annot.split('=')
                                if len(key_val) == 2:
                                    entry.add_annotation(key_val[0], key_val[1])
                            exon_entries.append(entry)
                            if entry.get_total_length() < 150:
                                gene_good = false
                        else:
                            gene_good = false

                        ## Write the annotations

                        ##### CDS
                        # Grab all CDSs under this mRNA
                        db_cur.execute('SELECT start, stop, strand, phase FROM tmp_cur_seq WHERE type="CDS" AND parent=?', [rna[0]])
                        CDSs = db_cur.fetchall()

                        if len(CDSs) > 0:
                            entry = FeatureTblEntry()
                            entry.set_type('CDS')
                            entry.set_partial_info(has_start, has_stop)
                            entry.set_strand(CDSs[0][2])
                            if CDSs[0][3] != '.':
                                entry.set_phase(int(CDSs[0][3]))
                            [entry.add_coordinates(CDS[0], CDS[1]) for CDS in CDSs]
                            cds_ann = cds_exon_ann_base+','+parse_gene_ontology(trinotate[8])
                            for annot in cds_ann.split(','):
                                key_val = annot.split('=')
                                if len(key_val) == 2:
                                    entry.add_annotation(key_val[0], key_val[1])
                            cds_entries.append(entry)
                            if entry.get_total_length() < 150:
                                gene_good = false
                        else:
                            gene_good = false

                    if len(exon_entries) != len(cds_entries):
                        gene_good = false
                    if gene_good:
                        f.write(gene_entry.write_to_string())
                        for i in range(len(exon_entries))
                            f.write(exon_entries[i].write_to_string())
                            f.write(cds_entries[i].write_to_string())
                    else:
                        print("Removed bad gene ", gene[5])

                db_cur.execute('DROP TABLE tmp_cur_seq')
<commit_msg>d00d it's False, not false<commit_after>#!/usr/bin/env python

import sqlite3
import re
from feature_tbl_entry import FeatureTblEntry

def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

# Takes blast hit and returns it as a CSV of key=value
def parse_blast_hit_gene(blast_hit):
    if len(blast_hit) == 0 or blast_hit == '.':
        return ''

    attributes = ''
    parts = blast_hit.split('`')

    part1_split = parts[0].split('|')
    attributes += "gene="+re.sub(r'_(.*)$', '', part1_split[2])

    return attributes

# Takes blast hit and returns it as a CSV of key=value
def parse_blast_hit_cds(blast_hit):
    if len(blast_hit) == 0 or blast_hit == '.':
        return 'product=hypothetical protein'

    attributes = ''
    parts = blast_hit.split('`')

    matchObj = re.search( r'RecName: Full=([^;]*)', blast_hit)
    if matchObj:
        attributes += "product="+matchObj.group(1)
    else:
        attributes += "product=hypothetical protein"

    return attributes

# Takes gene ontology and returns it as a CSV of key=value
def parse_gene_ontology(gene_ontology):
    if len(gene_ontology) == 0 or gene_ontology == '.':
        return ''

    attributes = ''
    elements = gene_ontology.split('`')
    for element in elements:
        if len(attributes) > 0:
            attributes += ','

	element = element.replace(',', '')
        vals = element.split('^')
        if vals[1] == 'molecular_function':
            attributes += 'go_function='
        elif vals[1] == 'cellular_component':
            attributes += 'go_component='
        elif vals[1] == 'biological_process':
            attributes += 'go_process='
        attributes += vals[2]+'|'+vals[0][3:]+'||IEA'
    return attributes

def reverse_indices(row):
    tmp = row[0]
    row[0] = row[1]
    row[1] = tmp
    return row

class FeatureTblWriter:

    def write_to_file(self, db_conn, fileName):
        db_conn.create_function('regexp', 2, regexp)

        db_cur = db_conn.cursor()

        with open(fileName, 'w') as f:
            ## Stupid first line??
            f.write('>Feature SeqId\n')

            # Get the sequence ids
            db_cur.execute('SELECT * FROM fasta')

            i = 0
            for seq in db_cur.fetchall():
                i += 1
                if i%100 == 0:
                    print(i)

                f.write('>Feature '+seq[0]+'\n')
                f.write('1\t'+str(len(seq[1]))+'\tREFERENCE\n')
                f.write('\t\t\tPBARC\t12345\n')

                # Create the temporary table
                # db_cur.execute('CREATE TABLE tmp_cur_seq(id TEXT PRIMARY KEY, seq_id TEXT, type TEXT, start INT, stop INT, name TEXT, parent TEXT)')

                # TODO: Match columns up with gff columns (i.e. strand isn't last in gff table)
                magic_query = "CREATE TEMP TABLE tmp_cur_seq AS SELECT id, seq_id, type, start, stop, name, parent, strand, phase FROM gff WHERE seq_id=?"

                # Store temporary table of all info pertaining to this sequence
                db_cur.execute(magic_query, [seq[0]])

                # Grab the genes on this sequence
                db_cur.execute('SELECT * FROM tmp_cur_seq WHERE type="gene"')
                genes = db_cur.fetchall()

                for gene in genes:
                    # Whether or not the gene is good to write
                    gene_good = True
                    exon_entries = []
                    cds_entries = []

                    # Find a trinotate entry to give us the gene id for this gene
                    db_cur.execute('SELECT top_blast_hit FROM trinotate WHERE prot_id REGEXP ? LIMIT 1', [gene[5]])
                    trinotate = db_cur.fetchone()

                    # Write the gene
                    gene_entry = FeatureTblEntry()
                    gene_entry.set_type('gene')
                    gene_entry.set_strand(gene[7])
                    gene_entry.set_partial_info(True, True)
                    if gene[8] != '.':
                        gene_entry.set_phase(int(gene[8]))
                    gene_entry.add_coordinates(gene[3], gene[4])
                    gene_ann = 'locus_tag='+gene[5]
                    if trinotate:
                        gene_ann += ','+parse_blast_hit_gene(trinotate[0])
                    for annot in gene_ann.split(','):
                        key_val = annot.split('=')
                        if len(key_val) == 2:
                            gene_entry.add_annotation(key_val[0], key_val[1])
                    if gene_entry.get_total_length() < 150:
                        gene_good = False

                    # Grab the mRNAs on this sequence
                    db_cur.execute('SELECT * FROM tmp_cur_seq WHERE type="mRNA" AND parent=?', [gene[0]])
                    rnas = db_cur.fetchall()

                    for rna in rnas:
                        # Grab the trinotate entry
                        trinotate = None
                        if re.match( r'maker', rna[5]):
                            db_cur.execute('SELECT * FROM trinotate WHERE prot_id=? LIMIT 1', [rna[5]])
                        else:
                            stripped_prot_id = re.sub(r'\.(\d*)', '', rna[5])
                            db_cur.execute('SELECT * FROM trinotate WHERE prot_id=? LIMIT 1', [stripped_prot_id])
                            trinotate = db_cur.fetchone()

                        if not trinotate:
                            print("Couldn't find annotation for "+rna[5]+". Skipping...")
                            continue

                        # Get whether the sequence has start and stop codons
                        db_cur.execute('SELECT EXISTS(SELECT type, name FROM tmp_cur_seq WHERE type="start_codon" AND parent=? LIMIT 1)', [rna[0]])
                        has_start = db_cur.fetchone()[0]
                        db_cur.execute('SELECT EXISTS(SELECT type, name FROM tmp_cur_seq WHERE type="stop_codon" AND parent=? LIMIT 1)', [rna[0]])
                        has_stop = db_cur.fetchone()[0]

                        # Annotation stuff
                        split_prot_id = rna[5].split('_')
                        cds_exon_ann_base = ''
                        cds_exon_ann_base += 'protein_id='+'gnl|PBARC|'+rna[5]+','
                        cds_exon_ann_base += 'transcript_id='+'gnl|PBARC|'+split_prot_id[0]+'_mrna'+split_prot_id[1]+','
                        cds_exon_ann_base += parse_blast_hit_cds(trinotate[3])

                        ##### EXON
                        # Grab all exons under this mRNA
                        db_cur.execute('SELECT start, stop, strand, phase FROM tmp_cur_seq WHERE type="exon" AND parent=?', [rna[0]])
                        exons = db_cur.fetchall()

                        if len(exons) > 0:
                            entry = FeatureTblEntry()
                            entry.set_type('mRNA') # Exons are actually mRNA?
                            entry.set_partial_info(has_start, has_stop)
                            entry.set_strand(exons[0][2])
                            if exons[0][3] != '.':
                                entry.set_phase(int(exons[0][3]))
                            [entry.add_coordinates(exon[0], exon[1]) for exon in exons]
                            exon_ann = cds_exon_ann_base
                            for annot in exon_ann.split(','):
                                key_val = annot.split('=')
                                if len(key_val) == 2:
                                    entry.add_annotation(key_val[0], key_val[1])
                            exon_entries.append(entry)
                            if entry.get_total_length() < 150:
                                gene_good = False
                        else:
                            gene_good = False

                        ## Write the annotations

                        ##### CDS
                        # Grab all CDSs under this mRNA
                        db_cur.execute('SELECT start, stop, strand, phase FROM tmp_cur_seq WHERE type="CDS" AND parent=?', [rna[0]])
                        CDSs = db_cur.fetchall()

                        if len(CDSs) > 0:
                            entry = FeatureTblEntry()
                            entry.set_type('CDS')
                            entry.set_partial_info(has_start, has_stop)
                            entry.set_strand(CDSs[0][2])
                            if CDSs[0][3] != '.':
                                entry.set_phase(int(CDSs[0][3]))
                            [entry.add_coordinates(CDS[0], CDS[1]) for CDS in CDSs]
                            cds_ann = cds_exon_ann_base+','+parse_gene_ontology(trinotate[8])
                            for annot in cds_ann.split(','):
                                key_val = annot.split('=')
                                if len(key_val) == 2:
                                    entry.add_annotation(key_val[0], key_val[1])
                            cds_entries.append(entry)
                            if entry.get_total_length() < 150:
                                gene_good = False
                        else:
                            gene_good = False

                    if len(exon_entries) != len(cds_entries):
                        gene_good = False
                    if gene_good:
                        f.write(gene_entry.write_to_string())
                        for i in range(len(exon_entries)):
                            f.write(exon_entries[i].write_to_string())
                            f.write(cds_entries[i].write_to_string())
                    else:
                        print("Removed bad gene ", gene[5])

                db_cur.execute('DROP TABLE tmp_cur_seq')
<|endoftext|>