<commit_before># vim:set fileencoding=utf-8
from unittest.mock import patch, PropertyMock
import unittest
import os
import six
import blivet
import gi
gi.require_version("BlockDev", "2.0")
from gi.repository import BlockDev as blockdev

from blivet.errors import DependencyError

from blivet.deviceaction import ActionCreateDevice
from blivet.deviceaction import ActionDestroyDevice
from blivet.deviceaction import ActionResizeDevice

from blivet.deviceaction import ActionCreateFormat
from blivet.deviceaction import ActionDestroyFormat

from blivet.devices import DiskDevice
from blivet.devices import LUKSDevice
from blivet.devices import MDRaidArrayDevice
from blivet.devices import PartitionDevice
from blivet.devices import StorageDevice

from blivet.formats import get_format

from blivet.size import Size

from blivet.tasks import availability

from blivet.util import create_sparse_tempfile

class DeviceDependenciesTestCase(unittest.TestCase):

    """Test external device dependencies. """

    def test_dependencies(self):
        dev1 = DiskDevice("name", fmt=get_format("mdmember"))
        dev2 = DiskDevice("other", fmt=get_format("mdmember"))
        dev = MDRaidArrayDevice("dev", level="raid1", parents=[dev1, dev2])
        luks = LUKSDevice("luks", parents=[dev])

        # a parent's dependencies are a subset of its child's.
        for d in dev.external_dependencies:
            self.assertIn(d, luks.external_dependencies)

        # make sure that there's at least something in these dependencies
        self.assertGreater(len(luks.external_dependencies), 0)

class MockingDeviceDependenciesTestCase1(unittest.TestCase):

    """Test availability of external device dependencies. """

    def setUp(self):
        dev1 = DiskDevice("name", fmt=get_format("mdmember"), size=Size("1 GiB"))
        dev2 = DiskDevice("other")
        self.part = PartitionDevice("part", fmt=get_format("mdmember"), parents=[dev2])
        self.dev = MDRaidArrayDevice("dev", level="raid1", parents=[dev1, self.part], fmt=get_format("luks"), total_devices=2, member_devices=2)
        self.luks = LUKSDevice("luks", parents=[self.dev], fmt=get_format("ext4"))

        self.mdraid_method = availability.BLOCKDEV_MDRAID_PLUGIN._method
        self.dm_method = availability.BLOCKDEV_DM_PLUGIN._method
        self.cache_availability = availability.CACHE_AVAILABILITY

        self.addCleanup(self._clean_up)

    def test_availability_mdraidplugin(self):

        availability.CACHE_AVAILABILITY = False
        availability.BLOCKDEV_DM_PLUGIN._method = availability.AvailableMethod

        # if the plugin is not in, there's nothing to test
        self.assertIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.external_dependencies)

        # dev is not among its unavailable dependencies
        availability.BLOCKDEV_MDRAID_PLUGIN._method = availability.AvailableMethod
        availability.MKFS_HFSPLUS_APP._method = availability.AvailableMethod  # macefi
        self.assertNotIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.unavailable_dependencies)
        self.assertIsNotNone(ActionCreateDevice(self.luks))
        self.assertIsNotNone(ActionDestroyDevice(self.luks))
        self.assertIsNotNone(ActionCreateFormat(self.luks, fmt=get_format("macefi")))
        self.assertIsNotNone(ActionDestroyFormat(self.luks))

        # dev is among the unavailable dependencies
        availability.BLOCKDEV_MDRAID_PLUGIN._method = availability.UnavailableMethod
        self.assertIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.unavailable_dependencies)
        with self.assertRaises(DependencyError):
            ActionCreateDevice(self.luks)
        with self.assertRaises(DependencyError):
            ActionDestroyDevice(self.dev)
        with self.assertRaises(DependencyError):
            ActionCreateFormat(self.dev)
        with self.assertRaises(DependencyError):
            ActionDestroyFormat(self.dev)

    def _clean_up(self):
        availability.BLOCKDEV_MDRAID_PLUGIN._method = self.mdraid_method
        availability.BLOCKDEV_DM_PLUGIN._method = self.dm_method

        availability.CACHE_AVAILABILITY = False
        availability.BLOCKDEV_MDRAID_PLUGIN.available  # pylint: disable=pointless-statement
        availability.BLOCKDEV_DM_PLUGIN.available  # pylint: disable=pointless-statement

        availability.CACHE_AVAILABILITY = self.cache_availability

class MockingDeviceDependenciesTestCase2(unittest.TestCase):
    def test_dependencies_handling(self):
        device = StorageDevice("testdev1")
        self.assertTrue(device.controllable)
        self.assertIsNotNone(ActionCreateDevice(device))
        device.exists = True
        self.assertIsNotNone(ActionDestroyDevice(device))
        with patch.object(StorageDevice, "resizable", new_callable=PropertyMock(return_value=True)):
            self.assertIsNotNone(ActionResizeDevice(device, Size("1 GiB")))

        # if any external dependency is missing, it should be impossible to create, destroy, setup,
        # teardown, or resize the device (controllable encompasses setup & teardown)
        with patch.object(StorageDevice, "_external_dependencies",
                          new_callable=PropertyMock(return_value=[availability.unavailable_resource("testing")])):
            device = StorageDevice("testdev1")
            self.assertFalse(device.controllable)
            self.assertRaises(DependencyError, ActionCreateDevice, device)
            device.exists = True
            self.assertRaises(DependencyError, ActionDestroyDevice, device)
            self.assertRaises(ValueError, ActionResizeDevice, device, Size("1 GiB"))

        # same goes for formats, except that the properties they affect vary by format class
        fmt = get_format("lvmpv")
        fmt._plugin = availability.available_resource("lvm-testing")
        self.assertTrue(fmt.supported)
        self.assertTrue(fmt.formattable)
        self.assertTrue(fmt.destroyable)

        fmt._plugin = availability.unavailable_resource("lvm-testing")
        self.assertFalse(fmt.supported)
        self.assertFalse(fmt.formattable)
        self.assertFalse(fmt.destroyable)

class MissingWeakDependenciesTestCase(unittest.TestCase):

    def setUp(self):
        self.addCleanup(self._clean_up)
        self.disk1_file = create_sparse_tempfile("disk1", Size("2GiB"))
        self.plugins = blockdev.plugin_specs_from_names(blockdev.get_available_plugin_names())

    def _clean_up(self):
        # reload all libblockdev plugins
        self.load_all_plugins()

        for disk in self.bvt.disks:
            self.bvt.recursive_remove(disk)

        self.bvt.devicetree.teardown_disk_images()
        for fn in self.bvt.disk_images.values():
            if os.path.exists(fn):
                os.unlink(fn)

    def load_all_plugins(self):
        result, plugins = blockdev.try_reinit(require_plugins=self.plugins, reload=True)
        if not result:
            self.fail("Could not reload libblockdev plugins")
        return plugins

    def unload_all_plugins(self):
        result, _ = blockdev.try_reinit(require_plugins=[], reload=True)
        if not result:
            self.fail("Could not reload libblockdev plugins")

    def test_weak_dependencies(self):
        self.bvt = blivet.Blivet()  # pylint: disable=attribute-defined-outside-init
        availability.CACHE_AVAILABILITY = False

        # reinitialize blockdev without the plugins
        # TODO: uncomment (workaround (1/2) for blivet.reset fail)
        # self.unload_all_plugins()
        self.bvt.disk_images["disk1"] = self.disk1_file
        self.bvt.exclusive_disks = self.bvt.disk_images["disk1"]
        try:
            self.bvt.reset()
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")
        # TODO: remove line (workaround (2/2) for blivet.reset fail)
        self.unload_all_plugins()

        disk1 = self.bvt.devicetree.get_device_by_name("disk1")

        with six.assertRaisesRegex(self, DependencyError, "requires unavailable_dependencies"):
            self.bvt.initialize_disk(disk1)

        pv = self.bvt.new_partition(size=Size("8GiB"), fmt_type="lvmpv")
        pv_fail = self.bvt.new_partition(size=Size("8GiB"), fmt_type="lvmpv")
        btrfs = self.bvt.new_partition(size=Size("1GiB"), fmt_type="btrfs")
        raid1 = self.bvt.new_partition(size=Size("1GiB"), fmt_type="mdmember")
        raid2 = self.bvt.new_partition(size=Size("1GiB"), fmt_type="mdmember")

        with six.assertRaisesRegex(self, ValueError, "resource to create this format.*unavailable"):
            self.bvt.create_device(pv_fail)

        # to be able to test functions like destroy_device it is necessary to have some
        # testing devices actually created - hence loading libblockdev plugins...
        self.load_all_plugins()
        self.bvt.create_device(pv)
        self.bvt.create_device(btrfs)
        # ... and unloading again when tests can continue
        self.unload_all_plugins()

        try:
            vg = self.bvt.new_vg(parents=[pv])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(vg)
        self.unload_all_plugins()

        try:
            lv1 = self.bvt.new_lv(fmt_type="ext4", size=Size("1GiB"), parents=[vg])
            lv2 = self.bvt.new_lv(fmt_type="ext4", size=Size("1GiB"), parents=[vg])
            lv3 = self.bvt.new_lv(fmt_type="luks", size=Size("1GiB"), parents=[vg])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(lv1)
        self.bvt.create_device(lv2)
        self.bvt.create_device(lv3)
        self.unload_all_plugins()

        try:
            pool = self.bvt.new_lv_from_lvs(vg, name='pool', seg_type="thin-pool", from_lvs=[lv1, lv2])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(pool)
        self.unload_all_plugins()

        with six.assertRaisesRegex(self, DependencyError, "requires unavailable_dependencies"):
            self.bvt.destroy_device(pool)

        try:
            self.bvt.new_btrfs(parents=[btrfs])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        with six.assertRaisesRegex(self, ValueError, "device cannot be resized"):
            self.bvt.resize_device(lv3, Size("2GiB"))

        try:
            self.bvt.new_tmp_fs(fmt=disk1.format, size=Size("500MiB"))
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        try:
            self.bvt.new_mdarray(level='raid0', parents=[raid1, raid2])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")
<commit_msg>Restore availability caching after disabling for tests.<commit_after># vim:set fileencoding=utf-8
from unittest.mock import patch, PropertyMock
import unittest
import os
import six
import blivet
import gi
gi.require_version("BlockDev", "2.0")
from gi.repository import BlockDev as blockdev

from blivet.errors import DependencyError

from blivet.deviceaction import ActionCreateDevice
from blivet.deviceaction import ActionDestroyDevice
from blivet.deviceaction import ActionResizeDevice

from blivet.deviceaction import ActionCreateFormat
from blivet.deviceaction import ActionDestroyFormat

from blivet.devices import DiskDevice
from blivet.devices import LUKSDevice
from blivet.devices import MDRaidArrayDevice
from blivet.devices import PartitionDevice
from blivet.devices import StorageDevice

from blivet.formats import get_format

from blivet.size import Size

from blivet.tasks import availability

from blivet.util import create_sparse_tempfile

class DeviceDependenciesTestCase(unittest.TestCase):

    """Test external device dependencies. """

    def test_dependencies(self):
        dev1 = DiskDevice("name", fmt=get_format("mdmember"))
        dev2 = DiskDevice("other", fmt=get_format("mdmember"))
        dev = MDRaidArrayDevice("dev", level="raid1", parents=[dev1, dev2])
        luks = LUKSDevice("luks", parents=[dev])

        # a parent's dependencies are a subset of its child's.
        for d in dev.external_dependencies:
            self.assertIn(d, luks.external_dependencies)

        # make sure that there's at least something in these dependencies
        self.assertGreater(len(luks.external_dependencies), 0)

class MockingDeviceDependenciesTestCase1(unittest.TestCase):

    """Test availability of external device dependencies. """

    def setUp(self):
        dev1 = DiskDevice("name", fmt=get_format("mdmember"), size=Size("1 GiB"))
        dev2 = DiskDevice("other")
        self.part = PartitionDevice("part", fmt=get_format("mdmember"), parents=[dev2])
        self.dev = MDRaidArrayDevice("dev", level="raid1", parents=[dev1, self.part], fmt=get_format("luks"), total_devices=2, member_devices=2)
        self.luks = LUKSDevice("luks", parents=[self.dev], fmt=get_format("ext4"))

        self.mdraid_method = availability.BLOCKDEV_MDRAID_PLUGIN._method
        self.dm_method = availability.BLOCKDEV_DM_PLUGIN._method
        self.cache_availability = availability.CACHE_AVAILABILITY

        self.addCleanup(self._clean_up)

    def test_availability_mdraidplugin(self):

        availability.CACHE_AVAILABILITY = False
        availability.BLOCKDEV_DM_PLUGIN._method = availability.AvailableMethod

        # if the plugin is not in, there's nothing to test
        self.assertIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.external_dependencies)

        # dev is not among its unavailable dependencies
        availability.BLOCKDEV_MDRAID_PLUGIN._method = availability.AvailableMethod
        availability.MKFS_HFSPLUS_APP._method = availability.AvailableMethod  # macefi
        self.assertNotIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.unavailable_dependencies)
        self.assertIsNotNone(ActionCreateDevice(self.luks))
        self.assertIsNotNone(ActionDestroyDevice(self.luks))
        self.assertIsNotNone(ActionCreateFormat(self.luks, fmt=get_format("macefi")))
        self.assertIsNotNone(ActionDestroyFormat(self.luks))

        # dev is among the unavailable dependencies
        availability.BLOCKDEV_MDRAID_PLUGIN._method = availability.UnavailableMethod
        self.assertIn(availability.BLOCKDEV_MDRAID_PLUGIN, self.luks.unavailable_dependencies)
        with self.assertRaises(DependencyError):
            ActionCreateDevice(self.luks)
        with self.assertRaises(DependencyError):
            ActionDestroyDevice(self.dev)
        with self.assertRaises(DependencyError):
            ActionCreateFormat(self.dev)
        with self.assertRaises(DependencyError):
            ActionDestroyFormat(self.dev)

    def _clean_up(self):
        availability.BLOCKDEV_MDRAID_PLUGIN._method = self.mdraid_method
        availability.BLOCKDEV_DM_PLUGIN._method = self.dm_method

        availability.CACHE_AVAILABILITY = False
        availability.BLOCKDEV_MDRAID_PLUGIN.available  # pylint: disable=pointless-statement
        availability.BLOCKDEV_DM_PLUGIN.available  # pylint: disable=pointless-statement

        availability.CACHE_AVAILABILITY = self.cache_availability

class MockingDeviceDependenciesTestCase2(unittest.TestCase):
    def test_dependencies_handling(self):
        device = StorageDevice("testdev1")
        self.assertTrue(device.controllable)
        self.assertIsNotNone(ActionCreateDevice(device))
        device.exists = True
        self.assertIsNotNone(ActionDestroyDevice(device))
        with patch.object(StorageDevice, "resizable", new_callable=PropertyMock(return_value=True)):
            self.assertIsNotNone(ActionResizeDevice(device, Size("1 GiB")))

        # if any external dependency is missing, it should be impossible to create, destroy, setup,
        # teardown, or resize the device (controllable encompasses setup & teardown)
        with patch.object(StorageDevice, "_external_dependencies",
                          new_callable=PropertyMock(return_value=[availability.unavailable_resource("testing")])):
            device = StorageDevice("testdev1")
            self.assertFalse(device.controllable)
            self.assertRaises(DependencyError, ActionCreateDevice, device)
            device.exists = True
            self.assertRaises(DependencyError, ActionDestroyDevice, device)
            self.assertRaises(ValueError, ActionResizeDevice, device, Size("1 GiB"))

        # same goes for formats, except that the properties they affect vary by format class
        fmt = get_format("lvmpv")
        fmt._plugin = availability.available_resource("lvm-testing")
        self.assertTrue(fmt.supported)
        self.assertTrue(fmt.formattable)
        self.assertTrue(fmt.destroyable)

        fmt._plugin = availability.unavailable_resource("lvm-testing")
        self.assertFalse(fmt.supported)
        self.assertFalse(fmt.formattable)
        self.assertFalse(fmt.destroyable)

class MissingWeakDependenciesTestCase(unittest.TestCase):

    def setUp(self):
        self.addCleanup(self._clean_up)
        self.disk1_file = create_sparse_tempfile("disk1", Size("2GiB"))
        self.plugins = blockdev.plugin_specs_from_names(blockdev.get_available_plugin_names())

    def _clean_up(self):
        # reload all libblockdev plugins
        self.load_all_plugins()

        for disk in self.bvt.disks:
            self.bvt.recursive_remove(disk)

        self.bvt.devicetree.teardown_disk_images()
        for fn in self.bvt.disk_images.values():
            if os.path.exists(fn):
                os.unlink(fn)
        availability.CACHE_AVAILABILITY = True

    def load_all_plugins(self):
        result, plugins = blockdev.try_reinit(require_plugins=self.plugins, reload=True)
        if not result:
            self.fail("Could not reload libblockdev plugins")
        return plugins

    def unload_all_plugins(self):
        result, _ = blockdev.try_reinit(require_plugins=[], reload=True)
        if not result:
            self.fail("Could not reload libblockdev plugins")

    def test_weak_dependencies(self):
        self.bvt = blivet.Blivet()  # pylint: disable=attribute-defined-outside-init
        availability.CACHE_AVAILABILITY = False

        # reinitialize blockdev without the plugins
        # TODO: uncomment (workaround (1/2) for blivet.reset fail)
        # self.unload_all_plugins()
        self.bvt.disk_images["disk1"] = self.disk1_file
        self.bvt.exclusive_disks = self.bvt.disk_images["disk1"]
        try:
            self.bvt.reset()
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")
        # TODO: remove line (workaround (2/2) for blivet.reset fail)
        self.unload_all_plugins()

        disk1 = self.bvt.devicetree.get_device_by_name("disk1")

        with six.assertRaisesRegex(self, DependencyError, "requires unavailable_dependencies"):
            self.bvt.initialize_disk(disk1)

        pv = self.bvt.new_partition(size=Size("8GiB"), fmt_type="lvmpv")
        pv_fail = self.bvt.new_partition(size=Size("8GiB"), fmt_type="lvmpv")
        btrfs = self.bvt.new_partition(size=Size("1GiB"), fmt_type="btrfs")
        raid1 = self.bvt.new_partition(size=Size("1GiB"), fmt_type="mdmember")
        raid2 = self.bvt.new_partition(size=Size("1GiB"), fmt_type="mdmember")

        with six.assertRaisesRegex(self, ValueError, "resource to create this format.*unavailable"):
            self.bvt.create_device(pv_fail)

        # to be able to test functions like destroy_device it is necessary to have some
        # testing devices actually created - hence loading libblockdev plugins...
        self.load_all_plugins()
        self.bvt.create_device(pv)
        self.bvt.create_device(btrfs)
        # ... and unloading again when tests can continue
        self.unload_all_plugins()

        try:
            vg = self.bvt.new_vg(parents=[pv])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(vg)
        self.unload_all_plugins()

        try:
            lv1 = self.bvt.new_lv(fmt_type="ext4", size=Size("1GiB"), parents=[vg])
            lv2 = self.bvt.new_lv(fmt_type="ext4", size=Size("1GiB"), parents=[vg])
            lv3 = self.bvt.new_lv(fmt_type="luks", size=Size("1GiB"), parents=[vg])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(lv1)
        self.bvt.create_device(lv2)
        self.bvt.create_device(lv3)
        self.unload_all_plugins()

        try:
            pool = self.bvt.new_lv_from_lvs(vg, name='pool', seg_type="thin-pool", from_lvs=[lv1, lv2])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        self.load_all_plugins()
        self.bvt.create_device(pool)
        self.unload_all_plugins()

        with six.assertRaisesRegex(self, DependencyError, "requires unavailable_dependencies"):
            self.bvt.destroy_device(pool)

        try:
            self.bvt.new_btrfs(parents=[btrfs])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        with six.assertRaisesRegex(self, ValueError, "device cannot be resized"):
            self.bvt.resize_device(lv3, Size("2GiB"))

        try:
            self.bvt.new_tmp_fs(fmt=disk1.format, size=Size("500MiB"))
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")

        try:
            self.bvt.new_mdarray(level='raid0', parents=[raid1, raid2])
        except blockdev.BlockDevNotImplementedError:  # pylint: disable=catching-non-exception
            self.fail("Improper handling of missing libblockdev plugin")
<|endoftext|>


<commit_before>import idaapi
import idautils
import idc
from .base import get_func
from ..core import set_name, get_ea, fix_addresses
from .line import Line

class Function(object):
    def __init__(self, ea):
        self._func = get_func(ea)

    def __eq__(self, other):
        try:
            return self.startEA == other.startEA
        except AttributeError:
            return False

    def __hash__(self):
        return self.startEA

    @property
    def lines(self):
        return iter_function_lines(self._func)

    @property
    def startEA(self):
        return self._func.startEA

    @property
    def endEA(self):
        return self._func.endEA

    @property
    def xrefs_to(self):
        return idautils.XrefsTo(self.startEA)

    @property
    def drefs_to(self):
        return idautils.DataRefsTo(self.startEA)

    @property
    def crefs_to(self):
        return idautils.CodeRefsTo(self.startEA, 1)

    @property
    def name(self):
        return idc.Name(self.startEA)

    @name.setter
    def name(self, name):
        self.set_name(name)

    def set_name(self, name, anyway=False):
        set_name(self.startEA, name, anyway=anyway)

    def __repr__(self):
        return 'Function(name="{}", addr=0x{:08X})'.format(self.name, self.startEA)

    @property
    def comment(self):
        return idaapi.get_func_cmt(self._func, False)

    @comment.setter
    def comment(self, value):
        idaapi.set_func_cmt(self._func, value, False)

    @property
    def frame_size(self):
        return idaapi.get_frame_size(self._func)

def iter_function_lines(func_ea):
    for line in idautils.FuncItems(get_ea(func_ea)):
        yield Line(line)

def iter_functions(start=None, end=None):
    start, end = fix_addresses(start, end)

    for func_t in idautils.Functions(start, end):
        yield Function(func_t)<commit_msg>Added `function.xrefs_from` for easy enumeration of all xrefs from a function.<commit_after>import idaapi
import idautils
import idc
from .base import get_func
from ..core import set_name, get_ea, fix_addresses
from .line import Line
from .xref import Xref

class Function(object):
    def __init__(self, ea):
        self._func = get_func(ea)

    def __eq__(self, other):
        try:
            return self.startEA == other.startEA
        except AttributeError:
            return False

    def __hash__(self):
        return self.startEA

    @property
    def lines(self):
        return iter_function_lines(self._func)

    @property
    def startEA(self):
        return self._func.startEA

    @property
    def endEA(self):
        return self._func.endEA

    @property
    def xrefs_from(self):
        for line in self.lines:
            for xref in line.xrefs_from:
                yield xref

    @property
    def drefs_from(self):
        for line in self.lines:
            for ea in line.drefs_from:
                yield ea

    @property
    def crefs_from(self):
        for line in self.lines:
            for ea in line.crefs_from:
                yield ea

    @property
    def xrefs_to(self):
        return map(Xref, idautils.XrefsTo(self.startEA))

    @property
    def drefs_to(self):
        return idautils.DataRefsTo(self.startEA)

    @property
    def crefs_to(self):
        return idautils.CodeRefsTo(self.startEA, 1)

    @property
    def name(self):
        return idc.Name(self.startEA)

    @name.setter
    def name(self, name):
        self.set_name(name)

    def set_name(self, name, anyway=False):
        set_name(self.startEA, name, anyway=anyway)

    def __repr__(self):
        return 'Function(name="{}", addr=0x{:08X})'.format(self.name, self.startEA)

    @property
    def comment(self):
        return idaapi.get_func_cmt(self._func, False)

    @comment.setter
    def comment(self, value):
        idaapi.set_func_cmt(self._func, value, False)

    @property
    def frame_size(self):
        return idaapi.get_frame_size(self._func)

def iter_function_lines(func_ea):
    for line in idautils.FuncItems(get_ea(func_ea)):
        yield Line(line)

def iter_functions(start=None, end=None):
    start, end = fix_addresses(start, end)

    for func_t in idautils.Functions(start, end):
        yield Function(func_t)<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

import re

from pyramid.scaffolds.template import Template
from pyramid.compat import input_

class BaseTemplate(Template):
    """
    A class that can be used as a base class for c2cgeoportal scaffolding
    templates.

    Greatly inspired from ``pyramid.scaffolds.template.PyramidTemplate``.
    """

    def pre(self, command, output_dir, vars):
        """
        Overrides ``pyramid.scaffold.template.Template.pre``, adding
        several variables to the default variables list. Also prevents
        common misnamings (such as naming a package "site" or naming a
        package logger "root").
        """

        if vars['package'] == 'site':
            raise ValueError(
                'Sorry, you may not name your package "site". '
                'The package name "site" has a special meaning in '
                'Python.  Please name it anything except "site".')

        package_logger = vars['package']
        if package_logger == 'root':
            # Rename the app logger in the rare case a project
            # is named 'root'
            package_logger = 'app'
        vars['package_logger'] = package_logger

        return Template.pre(self, command, output_dir, vars)

    def out(self, msg):  # pragma: no cover (replaceable testing hook)
        print(msg)

class TemplateCreate(BaseTemplate):
    _template_dir = 'create'
    summary = 'Template used to create a c2cgeoportal project'

    def pre(self, command, output_dir, vars):
        """
        Overrides the base template, adding the "srid" variable to
        the variables list.
        """
        self._set_srid_in_vars(command, vars)
        return BaseTemplate.pre(self, command, output_dir, vars)

    def post(self, command, output_dir, vars):  # pragma: no cover
        """
        Overrides the base template class to print "Welcome to c2cgeoportal!"
        after a successful scaffolding rendering.
        """

        self.out('Welcome to c2cgeoportal!')
        return BaseTemplate.post(self, command, output_dir, vars)

    def _set_srid_in_vars(self, command, vars):
        """
        Set the SRID into the vars dict.
        """
        srid = None
        for arg in command.args:
            m = re.match('srid=(\d+)', arg)
            if m:
                srid = m.group(1)
                break
        if srid is None:
            prompt = 'Spatial Reference System Identifier ' \
                     '(e.g. 21781): '
            srid = input_(prompt).strip()
        try:
            vars['srid'] = int(srid)
        except ValueError:
            raise ValueError(
                'Specified SRID is not an integer')

class TemplateUpdate(BaseTemplate):
    _template_dir = 'update'
    summary = 'Template used to update a c2cgeoportal project'
<commit_msg>pyramid 1.3 upgrade - support specifying the package name on the pcreate command line<commit_after># -*- coding: utf-8 -*-

import re

from pyramid.scaffolds.template import Template
from pyramid.compat import input_

class BaseTemplate(Template):
    """
    A class that can be used as a base class for c2cgeoportal scaffolding
    templates.

    Greatly inspired from ``pyramid.scaffolds.template.PyramidTemplate``.
    """

    def pre(self, command, output_dir, vars):
        """
        Overrides ``pyramid.scaffold.template.Template.pre``, adding
        several variables to the default variables list. Also prevents
        common misnamings (such as naming a package "site" or naming a
        package logger "root").
        """

        ret = Template.pre(self, command, output_dir, vars)

        self._set_package_in_vars(command, vars)

        if vars['package'] == 'site':
            raise ValueError(
                'Sorry, you may not name your package "site". '
                'The package name "site" has a special meaning in '
                'Python.  Please name it anything except "site".')

        package_logger = vars['package']
        if package_logger == 'root':
            # Rename the app logger in the rare case a project
            # is named 'root'
            package_logger = 'app'
        vars['package_logger'] = package_logger

        return ret

    def _set_package_in_vars(self, command, vars):
        """
        Set the package into the vars dict.
        """
        for arg in command.args:
            m = re.match('package=(\w+)', arg)
            if m:
                vars['package'] = m.group(1)
                break

    def out(self, msg):  # pragma: no cover (replaceable testing hook)
        print(msg)

class TemplateCreate(BaseTemplate):
    _template_dir = 'create'
    summary = 'Template used to create a c2cgeoportal project'

    def pre(self, command, output_dir, vars):
        """
        Overrides the base template, adding the "srid" variable to
        the variables list.
        """
        self._set_srid_in_vars(command, vars)
        return BaseTemplate.pre(self, command, output_dir, vars)

    def post(self, command, output_dir, vars):  # pragma: no cover
        """
        Overrides the base template class to print "Welcome to c2cgeoportal!"
        after a successful scaffolding rendering.
        """

        self.out('Welcome to c2cgeoportal!')
        return BaseTemplate.post(self, command, output_dir, vars)

    def _set_srid_in_vars(self, command, vars):
        """
        Set the SRID into the vars dict.
        """
        srid = None
        for arg in command.args:
            m = re.match('srid=(\d+)', arg)
            if m:
                srid = m.group(1)
                break
        if srid is None:
            prompt = 'Spatial Reference System Identifier ' \
                     '(e.g. 21781): '
            srid = input_(prompt).strip()
        try:
            vars['srid'] = int(srid)
        except ValueError:
            raise ValueError(
                'Specified SRID is not an integer')

class TemplateUpdate(BaseTemplate):
    _template_dir = 'update'
    summary = 'Template used to update a c2cgeoportal project'
<|endoftext|>


<commit_before>import json
import os
import sys
import datetime
import socket
import argparse

CUR_DIR = os.path.dirname(os.path.realpath(__file__))

class Event():

    def __init__(self, event_dict):
        try:
            self.start_time = event_dict['start']
            self.days = event_dict['days']
            self.minutes = event_dict['minutes']
            self.station = event_dict['station']
        except KeyError, e:
            sys.exit('Error reading schedule. Missing key: %s' % e)

    def __repr__(self):
        day_list = ['M','T','W','Th','F','S','Sn']
        days = ",".join([day_list[day-1] for day in self.days])
        return "Station %d, run %d minutes on %s @ %s" % \
            (self.station, self.minutes, days, self.start_time)

    def should_run_now(self):
        """
        Compares the current day number and time to the event to see
        if it's supposed to be running now.
        """
        now = datetime.datetime.now()
        day = now.isoweekday()
        # See if today is in the list of days to run
        if day in self.days:
            now_hour_min = now.strftime("%H:%M")
            if now_hour_min == self.start_time:
                return True
        # If none of the tests passed, we do not run
        return False

    @classmethod
    def log(self, message):
        """
        A convenience method for writing operations to a log file.
        """
        file_path = os.path.join(CUR_DIR, 'log.txt')
        f = open(file_path, 'a')
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        msg = '%s\t%s\t%s\n' % (now_time, os.getpid(), message)
        f.write(msg)
        print msg

if __name__ == "__main__":

    # Parse command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--file', required=True)
    args = vars(parser.parse_args())

    # Try to open up the filename that was passed
    try:
        file_path = os.path.abspath(args['file'])
        f = open(file_path, 'r')
        data = f.read()
        f.close()
    except IOError:
        sys.exit("Error opening schedule file: %s" % file_path)

    # Turn the contents of the json file into a Python list
    try:
        events = json.loads(data)
    except ValueError:
        sys.exit("Error in schedule.json syntax. Invalid JSON.")

    if type(events) is not list:
        sys.exit("Error in schedule.json syntax. Could not find events list.")

    # Loop over all the events and find the first one that should
    # be run now.
    for item in events:
        # Turn the event dictionary into an object
        event = Event(item)
        # See if the event is supposed to run this minute
        if event.should_run_now():
            Event.log("Running event: %s" % event)
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect(('localhost', 9999))
                sock.sendall("%s,%s" % (event.station, event.minutes))
                sock.close()
            except socket.error:
                Event.log("Error: Could not connect to socket")
            break
<commit_msg>Added a --dump flag to output the schedule in readable format.<commit_after>import json
import os
import sys
import datetime
import socket
import argparse

CUR_DIR = os.path.dirname(os.path.realpath(__file__))

class Event():

    def __init__(self, event_dict):
        try:
            self.start_time = event_dict['start']
            self.days = event_dict['days']
            self.minutes = event_dict['minutes']
            self.station = event_dict['station']
        except KeyError, e:
            sys.exit('Error reading schedule. Missing key: %s' % e)

    def __repr__(self):
        day_list = ['M','T','W','Th','F','S','Sn']
        days = ",".join([day_list[day-1] for day in self.days])
        return "Station %d, run %d minutes on %s @ %s" % \
            (self.station, self.minutes, days, self.start_time)

    def should_run_now(self):
        """
        Compares the current day number and time to the event to see
        if it's supposed to be running now.
        """
        now = datetime.datetime.now()
        day = now.isoweekday()
        # See if today is in the list of days to run
        if day in self.days:
            now_hour_min = now.strftime("%H:%M")
            if now_hour_min == self.start_time:
                return True
        # If none of the tests passed, we do not run
        return False

    @classmethod
    def log(self, message):
        """
        A convenience method for writing operations to a log file.
        """
        file_path = os.path.join(CUR_DIR, 'log.txt')
        f = open(file_path, 'a')
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        msg = '%s\t%s\t%s\n' % (now_time, os.getpid(), message)
        f.write(msg)
        print msg

if __name__ == "__main__":

    # Parse command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--file', required=True)
    parser.add_argument("--dump", action="store_true", dest="dump", default=False)
    args = vars(parser.parse_args())

    # Try to open up the filename that was passed
    try:
        file_path = os.path.abspath(args['file'])
        f = open(file_path, 'r')
        data = f.read()
        f.close()
    except IOError:
        sys.exit("Error opening schedule file: %s" % file_path)

    # Turn the contents of the json file into a Python list
    try:
        events = json.loads(data)
    except ValueError:
        sys.exit("Error in schedule.json syntax. Invalid JSON.")

    if type(events) is not list:
        sys.exit("Error in schedule.json syntax. Could not find events list.")

    # If we get a dump flag, we just want to output the schedule
    if args['dump']:
        for item in events:
            print Event(item)
        sys.exit()

    # Loop over all the events and find the first one that should
    # be run now.
    for item in events:
        # Turn the event dictionary into an object
        event = Event(item)
        # See if the event is supposed to run this minute
        if event.should_run_now():
            Event.log("Running event: %s" % event)
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect(('localhost', 9999))
                sock.sendall("%s,%s" % (event.station, event.minutes))
                sock.close()
            except socket.error:
                Event.log("Error: Could not connect to socket")
            break
<|endoftext|>


<commit_before>import sys
import time
import logging
logging.basicConfig(level=logging.DEBUG)

from redis import StrictRedis
from rq import Queue
from apscheduler.schedulers.blocking import BlockingScheduler

from glharvest import jobs

conn = StrictRedis(host='redis', port='6379')
q = Queue(connection=conn)

sched = BlockingScheduler()

@sched.scheduled_job('interval', minutes=1)
def queue_status_job():
    q.enqueue('glharvest.jobs.status')

@sched.scheduled_job('interval', hours=1)
def queue_update_job():
    q.enqueue('glharvest.jobs.update', timeout=600) # Timeout of 10min

@sched.scheduled_job('interval', hours=1)
def queue_export_job():
    q.enqueue('glharvest.jobs.export')

# Queue the status job syncrhonously so the test repo is created
# This is a workaround to a bug in Sesame that lets you create two repositories
# with the same ID which puts the database into an unusable state

time.sleep(10)
q.enqueue('glharvest.jobs.status')
q.enqueue('glharvest.jobs.update')

# Start the scheduler
sched.start()
<commit_msg>Clean up jobs file<commit_after>import sys
import time
import logging
logging.basicConfig(level=logging.DEBUG)

from redis import StrictRedis
from rq import Queue
from apscheduler.schedulers.blocking import BlockingScheduler

from glharvest import jobs

conn = StrictRedis(host='redis', port='6379')
q = Queue(connection=conn)

sched = BlockingScheduler()

@sched.scheduled_job('interval', minutes=1)
def queue_status_job():
    q.enqueue(glharvest.jobs.status)

@sched.scheduled_job('interval', minutes=1)
def queue_update_job():
    q.enqueue(glharvest.jobs.update, timeout=600) # Timeout of 10min

@sched.scheduled_job('interval', hours=1)
def queue_export_job():
    q.enqueue(glharvest.jobs.export)

# Wait a bit for Sesame to start
time.sleep(10)

# Queue the status job first. This creates the repository before any other
# jobs are run.
q.enqueue(glharvest.jobs.status)

# Start the scheduler
sched.start()
<|endoftext|>


<commit_before>import _ExocortexAlembicPython as alembic
import sys
import argparse

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def create_new_TS(tsampling, scale, offset):
   new_tss = []
   for sampling in tsampling:
      ts_type = sampling.getType()
      samples = sampling.getTimeSamples()

      if ts_type == "uniform":
         samples = samples[0] + offset
      else:
         tmp_ts = []
         K = samples[0] * (1.0 - scale) + offset
         for s in samples:
            tmp_ts.append( s*scale + K )
         samples = tmp_ts

      new_tss.append( alembic.createTimeSampling(ts_type, samples) )
   return new_tss

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
#copy directly a property and its corresponding values
def copy_property(prop, outProp):
   for i in xrange(0, prop.getNbStoredSamples()):
      vals = prop.getValues(i)
      outProp.setValues(vals)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
#visiting the structure, if it's a property, copy it, if it's a compound, continue the visit there
def copy_compound_property(cprop, outCprop):
   for prop_name in cprop.getPropertyNames():
      if prop_name == ".metadata":
         continue                                                    # .metadata cause some problem

      if prop.isCompound():
         out_prop = outCprop.getProperty(prop_name, prop.getType())
         copy_compound_property(prop, out_prop, out_data)
      else:
         curTS = prop.getSampleTimes()

         out_prop = None
         if len(curTS.getTimeSamples()) == 0:
            out_prop = outCprop.getProperty(prop_name, prop.getType())
         else:
            tsSampling = out_data.createTimeSampling([curTS])
            out_prop = outCprop.getProperty(prop_name, prop.getType(), tsSampling[0])

         copy_property(prop, out_prop)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
# going through each object
def copy_objects(in_data, out_data):
   for identifier in in_data.getIdentifiers():
      obj = in_data.getObject(identifier)
      obj_typ = obj.getType()

      curTS = obj.getSampleTimes()
      out = None
      if len(curTS.getTimeSamples()) == 0:
         out = out_data.createObject(obj_typ, identifier)
      else:
         tsSampling = out_data.createTimeSampling([curTS])
         out = out_data.createObject(obj_typ, identifier, tsSampling[0])

      out.setMetaData(obj.getMetaData())
      for prop_name in obj.getPropertyNames():
         if prop_name == ".metadata":
            continue                                              # .metadata cause some problem

         prop = obj.getProperty(prop_name)

         if prop.isCompound():
            out_prop = out.getProperty(prop_name, prop.getType())
            copy_compound_property(prop, out_prop, out_data)
         else:
            curTS = prop.getSampleTimes()

            out_prop = None
            if len(curTS.getTimeSamples()) == 0:
               out_prop = out.getProperty(prop_name, prop.getType())
            else:
               tsSampling = out_data.createTimeSampling([curTS])
               out_prop = out.getProperty(prop_name, prop.getType(), tsSampling[0])

            copy_property(prop, out_prop)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def main(args):
   # parser args
   parser = argparse.ArgumentParser(description="Copy an alembic file into a new one by changing it's time sampling.\n\nNote that this program doesn't validate the time sampling. It's possible to create time samplings with negative values.")
   parser.add_argument("abc_in", type=str,   metavar="{Alembic input file}",  help="input alembic file to be copied and retimed")
   parser.add_argument("-o",     type=str,   metavar="{Alembic output file}", help="optional output file name, default is \"a.abc\"", default="a.abc")
   parser.add_argument("-s",     type=float, metavar="{scaling factor}",      help="scaling factor, default is 1.0",                  default=1.0)
   parser.add_argument("-a",     type=float, metavar="{offset}",              help="offset for the time sampling, default is 0.0",    default=0.0)
   ns = vars(parser.parse_args(args[1:]))

   if ns["abc_in"] == ns["o"]:
      print("Error: input and output filenames must be different")
      return

   scale  = ns["s"]
   offset = ns["a"]

   if scale <= 0.0:
      print("Error: the scale factor cannot be less or equal to zero")
      return

   in_data  = alembic.getIArchive(ns["abc_in"])
   out_data = alembic.getOArchive(ns["o"])
   ori_ts = in_data.getSampleTimes()
   new_ts = create_new_TS(ori_ts, scale, offset)
   out_data.createTimeSampling(new_ts)
   copy_objects(in_data, out_data)

   print("\n\n")

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__":
   main(sys.argv)

<commit_msg>again retime.py #57<commit_after>import _ExocortexAlembicPython as alembic
import sys
import argparse

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def create_new_TS(tsampling, scale, offset):
   new_tss = []
   for sampling in tsampling:
      ts_type = sampling.getType()
      samples = sampling.getTimeSamples()

      if ts_type == "uniform":
         samples = samples[0] * offset
      else:
         tmp_ts = []
         K = samples[0] * (1.0 - scale) + offset
         for s in samples:
            tmp_ts.append( s*scale + K )
         samples = tmp_ts

      new_tss.append( alembic.createTimeSampling(ts_type, samples) )
   return new_tss

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
#copy directly a property and its corresponding values
def copy_property(prop, outProp):
   for i in xrange(0, prop.getNbStoredSamples()):
      vals = prop.getValues(i)
      outProp.setValues(vals)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
#visiting the structure, if it's a property, copy it, if it's a compound, continue the visit there
def copy_compound_property(cprop, outCprop):
   for prop_name in cprop.getPropertyNames():
      if prop_name == ".metadata":
         continue                                                    # .metadata cause some problem

      if prop.isCompound():
         out_prop = outCprop.getProperty(prop_name, prop.getType())
         copy_compound_property(prop, out_prop, out_data)
      else:
         curTS = prop.getSampleTimes()

         out_prop = None
         if len(curTS.getTimeSamples()) == 0:
            out_prop = outCprop.getProperty(prop_name, prop.getType())
         else:
            tsSampling = out_data.createTimeSampling([curTS])
            out_prop = outCprop.getProperty(prop_name, prop.getType(), tsSampling[0])

         copy_property(prop, out_prop)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
# going through each object
def copy_objects(in_data, out_data):
   for identifier in in_data.getIdentifiers():
      obj = in_data.getObject(identifier)
      obj_typ = obj.getType()

      curTS = obj.getSampleTimes()
      out = None
      if len(curTS.getTimeSamples()) == 0:
         out = out_data.createObject(obj_typ, identifier)
      else:
         tsSampling = out_data.createTimeSampling([curTS])
         out = out_data.createObject(obj_typ, identifier, tsSampling[0])

      out.setMetaData(obj.getMetaData())
      for prop_name in obj.getPropertyNames():
         if prop_name == ".metadata":
            continue                                              # .metadata cause some problem

         prop = obj.getProperty(prop_name)

         if prop.isCompound():
            out_prop = out.getProperty(prop_name, prop.getType())
            copy_compound_property(prop, out_prop, out_data)
         else:
            curTS = prop.getSampleTimes()

            out_prop = None
            if len(curTS.getTimeSamples()) == 0:
               out_prop = out.getProperty(prop_name, prop.getType())
            else:
               tsSampling = out_data.createTimeSampling([curTS])
               out_prop = out.getProperty(prop_name, prop.getType(), tsSampling[0])

            copy_property(prop, out_prop)

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def main(args):
   # parser args
   parser = argparse.ArgumentParser(description="Copy an alembic file into a new one by changing it's time sampling.\n\nNote that this program doesn't validate the time sampling. It's possible to create time samplings with negative values.")
   parser.add_argument("abc_in", type=str,   metavar="{Alembic input file}",  help="input alembic file to be copied and retimed")
   parser.add_argument("-o",     type=str,   metavar="{Alembic output file}", help="optional output file name, default is \"a.abc\"", default="a.abc")
   parser.add_argument("-s",     type=float, metavar="{scaling factor}",      help="scaling factor, default is 1.0",                  default=1.0)
   parser.add_argument("-a",     type=float, metavar="{offset}",              help="offset for the time sampling, default is 0.0",    default=0.0)
   ns = vars(parser.parse_args(args[1:]))

   if ns["abc_in"] == ns["o"]:
      print("Error: input and output filenames must be different")
      return

   scale  = ns["s"]
   offset = ns["a"]

   if scale <= 0.0:
      print("Error: the scale factor cannot be less or equal to zero")
      return

   in_data  = alembic.getIArchive(ns["abc_in"])
   out_data = alembic.getOArchive(ns["o"])
   ori_ts = in_data.getSampleTimes()
   new_ts = create_new_TS(ori_ts, scale, offset)
   out_data.createTimeSampling(new_ts)
   copy_objects(in_data, out_data)

   print("\n\n")

# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__":
   main(sys.argv)

<|endoftext|>


<commit_before>from collections import namedtuple
import requests

from .tasks import Task

TASK_TYPES = [
    'categorization',
    'transcription',
    'phonecall',
    'comparison',
    'annotation',
    'polygonannotation',
    'lineannotation',
    'datacollection',
    'audiotranscription',
    'pointannotation',
    'cuboidannotation',
    'segmentannotation'
]
SCALE_ENDPOINT = 'https://api.scale.com/v1/'
DEFAULT_LIMIT = 100
DEFAULT_OFFSET = 0

class ScaleException(Exception):
    def __init__(self, message, errcode):
        super(ScaleException, self).__init__('<Response [{}]> {}'.format(errcode, message))
        self.code = errcode

class ScaleInvalidRequest(ScaleException, ValueError):
    pass

class Tasklist(list):
    def __init__(self, docs, total, limit, offset, has_more):
        super(Tasklist, self).__init__(docs)
        self.docs = docs
        self.total = total
        self.limit = limit
        self.offset = offset
        self.has_more = has_more

class ScaleClient(object):
    def __init__(self, api_key):
        self.api_key = api_key

    def _getrequest(self, endpoint, params={}):
        """Makes a get request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        r = requests.get(SCALE_ENDPOINT + endpoint,
                         headers={"Content-Type": "application/json"},
                         auth=(self.api_key, ''), params=params)

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def _postrequest(self, endpoint, payload=None):
        """Makes a post request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        payload = payload or {}
        r = requests.post(SCALE_ENDPOINT + endpoint, json=payload,
                          headers={"Content-Type": "application/json"},
                          auth=(self.api_key, ''))

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def fetch_task(self, task_id):
        """Fetches a task.

        Returns the associated task.
        """
        return Task(self._getrequest('task/%s' % task_id), self)

    def cancel_task(self, task_id):
        """Cancels a task.

        Returns the associated task.
        Raises a ScaleException if it has already been canceled.
        """
        return Task(self._postrequest('task/%s/cancel' % task_id), self)

    def tasks(self, **kwargs):
        """Returns a list of your tasks.
        Returns up to 100 at a time, to get more use the offset param.

        start/end_time are ISO8601 dates, the time range of tasks to fetch.
        status can be 'completed', 'pending', or 'canceled'.
        type is the task type.
        limit is the max number of results to display per page,
        offset is the number of results to skip (for showing more pages).
        """
        allowed_kwargs = {'start_time', 'end_time', 'status', 'type', 'project',
                          'batch', 'limit', 'offset'}
        for key in kwargs:
            if key not in allowed_kwargs:
                raise ScaleInvalidRequest('Illegal parameter %s for ScaleClient.tasks()'
                                          % key, None)
        response = self._getrequest('tasks', params=kwargs)
        docs = [Task(json, self) for json in response['docs']]
        return Tasklist(docs, response['total'], response['limit'],
                        response['offset'], response['has_more'])
    def create_task(self, task_type, **kwargs):
        endpoint = 'task/' + task_type
        taskdata = self._postrequest(endpoint, payload=kwargs)
        return Task(taskdata, self)

def _AddTaskTypeCreator(task_type):
    def create_task_wrapper(self, **kwargs):
        return self.create_task(task_type, **kwargs)
    setattr(ScaleClient, 'create_' + task_type + '_task', create_task_wrapper)

for taskType in TASK_TYPES:
    _AddTaskTypeCreator(taskType)
<commit_msg>add arguments to list all tasks<commit_after>from collections import namedtuple
import requests

from .tasks import Task

TASK_TYPES = [
    'categorization',
    'transcription',
    'phonecall',
    'comparison',
    'annotation',
    'polygonannotation',
    'lineannotation',
    'datacollection',
    'audiotranscription',
    'pointannotation',
    'cuboidannotation',
    'segmentannotation'
]
SCALE_ENDPOINT = 'https://api.scale.com/v1/'
DEFAULT_LIMIT = 100
DEFAULT_OFFSET = 0

class ScaleException(Exception):
    def __init__(self, message, errcode):
        super(ScaleException, self).__init__('<Response [{}]> {}'.format(errcode, message))
        self.code = errcode

class ScaleInvalidRequest(ScaleException, ValueError):
    pass

class Tasklist(list):
    def __init__(self, docs, total, limit, offset, has_more):
        super(Tasklist, self).__init__(docs)
        self.docs = docs
        self.total = total
        self.limit = limit
        self.offset = offset
        self.has_more = has_more

class ScaleClient(object):
    def __init__(self, api_key):
        self.api_key = api_key

    def _getrequest(self, endpoint, params={}):
        """Makes a get request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        r = requests.get(SCALE_ENDPOINT + endpoint,
                         headers={"Content-Type": "application/json"},
                         auth=(self.api_key, ''), params=params)

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def _postrequest(self, endpoint, payload=None):
        """Makes a post request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        payload = payload or {}
        r = requests.post(SCALE_ENDPOINT + endpoint, json=payload,
                          headers={"Content-Type": "application/json"},
                          auth=(self.api_key, ''))

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def fetch_task(self, task_id):
        """Fetches a task.

        Returns the associated task.
        """
        return Task(self._getrequest('task/%s' % task_id), self)

    def cancel_task(self, task_id):
        """Cancels a task.

        Returns the associated task.
        Raises a ScaleException if it has already been canceled.
        """
        return Task(self._postrequest('task/%s/cancel' % task_id), self)

    def tasks(self, **kwargs):
        """Returns a list of your tasks.
        Returns up to 100 at a time, to get more use the offset param.

        start/end_time are ISO8601 dates, the time range of tasks to fetch.
        status can be 'completed', 'pending', or 'canceled'.
        type is the task type.
        limit is the max number of results to display per page,
        offset is the number of results to skip (for showing more pages).
        """
        allowed_kwargs = {'start_time', 'end_time', 'status', 'type', 'project',
                          'batch', 'limit', 'offset', 'completed_before', 'completed_after'}
        for key in kwargs:
            if key not in allowed_kwargs:
                raise ScaleInvalidRequest('Illegal parameter %s for ScaleClient.tasks()'
                                          % key, None)
        response = self._getrequest('tasks', params=kwargs)
        docs = [Task(json, self) for json in response['docs']]
        return Tasklist(docs, response['total'], response['limit'],
                        response['offset'], response['has_more'])
    def create_task(self, task_type, **kwargs):
        endpoint = 'task/' + task_type
        taskdata = self._postrequest(endpoint, payload=kwargs)
        return Task(taskdata, self)

def _AddTaskTypeCreator(task_type):
    def create_task_wrapper(self, **kwargs):
        return self.create_task(task_type, **kwargs)
    setattr(ScaleClient, 'create_' + task_type + '_task', create_task_wrapper)

for taskType in TASK_TYPES:
    _AddTaskTypeCreator(taskType)
<|endoftext|>


<commit_before>from collections import namedtuple
import requests

from .tasks import Task

TASK_TYPES = [
    'categorization',
    'transcription',
    'phonecall',
    'comparison',
    'annotation',
    'polygonannotation',
    'lineannotation',
    'datacollection',
    'audiotranscription',
    'pointannotation',
    'cuboidannotation',
    'segmentannotation',
    'namedentityrecognition'
]
SCALE_ENDPOINT = 'https://api.scale.com/v1/'
DEFAULT_LIMIT = 100
DEFAULT_OFFSET = 0

class ScaleException(Exception):
    def __init__(self, message, errcode):
        super(ScaleException, self).__init__('<Response [{}]> {}'.format(errcode, message))
        self.code = errcode

class ScaleInvalidRequest(ScaleException, ValueError):
    pass

class Tasklist(list):
    def __init__(self, docs, total, limit, offset, has_more, next_token=None):
        super(Tasklist, self).__init__(docs)
        self.docs = docs
        self.total = total
        self.limit = limit
        self.offset = offset
        self.has_more = has_more
        self.next_token = next_token

class ScaleClient(object):
    def __init__(self, api_key):
        self.api_key = api_key

    def _getrequest(self, endpoint, params={}):
        """Makes a get request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        r = requests.get(SCALE_ENDPOINT + endpoint,
                         headers={"Content-Type": "application/json"},
                         auth=(self.api_key, ''), params=params)

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def _postrequest(self, endpoint, payload=None):
        """Makes a post request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        payload = payload or {}
        r = requests.post(SCALE_ENDPOINT + endpoint, json=payload,
                          headers={"Content-Type": "application/json"},
                          auth=(self.api_key, ''))

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def fetch_task(self, task_id):
        """Fetches a task.

        Returns the associated task.
        """
        return Task(self._getrequest('task/%s' % task_id), self)

    def cancel_task(self, task_id):
        """Cancels a task.

        Returns the associated task.
        Raises a ScaleException if it has already been canceled.
        """
        return Task(self._postrequest('task/%s/cancel' % task_id), self)

    def tasks(self, **kwargs):
        """Returns a list of your tasks.
        Returns up to 100 at a time, to get more, use the next_token param passed back.

        Note that offset is deprecated.

        start/end_time are ISO8601 dates, the time range of tasks to fetch.
        status can be 'completed', 'pending', or 'canceled'.
        type is the task type.
        limit is the max number of results to display per page,
        next_token can be use to fetch the next page of tasks.
        offset (deprecated) is the number of results to skip (for showing more pages).
        """
        allowed_kwargs = {'start_time', 'end_time', 'status', 'type', 'project',
                          'batch', 'limit', 'offset', 'completed_before', 'completed_after',
                          'next_token'}
        for key in kwargs:
            if key not in allowed_kwargs:
                raise ScaleInvalidRequest('Illegal parameter %s for ScaleClient.tasks()'
                                          % key, None)
        response = self._getrequest('tasks', params=kwargs)
        docs = [Task(json, self) for json in response['docs']]
        return Tasklist(docs, response['total'], response['limit'],
                        response['offset'], response['has_more'], response.get('next_token'))
    def create_task(self, task_type, **kwargs):
        endpoint = 'task/' + task_type
        taskdata = self._postrequest(endpoint, payload=kwargs)
        return Task(taskdata, self)

def _AddTaskTypeCreator(task_type):
    def create_task_wrapper(self, **kwargs):
        return self.create_task(task_type, **kwargs)
    setattr(ScaleClient, 'create_' + task_type + '_task', create_task_wrapper)

for taskType in TASK_TYPES:
    _AddTaskTypeCreator(taskType)
<commit_msg>Update list of task types<commit_after>from collections import namedtuple
import requests

from .tasks import Task

TASK_TYPES = [
    'annotation',
    'audiotranscription',
    'categorization',
    'comparison',
    'cuboidannotation',
    'datacollection',
    'imageannotation',
    'lineannotation',
    'namedentityrecognition',
    'pointannotation',
    'polygonannotation',
    'segmentannotation',
    'transcription',
    'videoannotation',
    'videoboxannotation',
    'videocuboidannotation'
]
SCALE_ENDPOINT = 'https://api.scale.com/v1/'
DEFAULT_LIMIT = 100
DEFAULT_OFFSET = 0

class ScaleException(Exception):
    def __init__(self, message, errcode):
        super(ScaleException, self).__init__('<Response [{}]> {}'.format(errcode, message))
        self.code = errcode

class ScaleInvalidRequest(ScaleException, ValueError):
    pass

class Tasklist(list):
    def __init__(self, docs, total, limit, offset, has_more, next_token=None):
        super(Tasklist, self).__init__(docs)
        self.docs = docs
        self.total = total
        self.limit = limit
        self.offset = offset
        self.has_more = has_more
        self.next_token = next_token

class ScaleClient(object):
    def __init__(self, api_key):
        self.api_key = api_key

    def _getrequest(self, endpoint, params={}):
        """Makes a get request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        r = requests.get(SCALE_ENDPOINT + endpoint,
                         headers={"Content-Type": "application/json"},
                         auth=(self.api_key, ''), params=params)

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def _postrequest(self, endpoint, payload=None):
        """Makes a post request to an endpoint.

        If an error occurs, assumes that endpoint returns JSON as:
            { 'status_code': XXX,
              'error': 'I failed' }
        """
        payload = payload or {}
        r = requests.post(SCALE_ENDPOINT + endpoint, json=payload,
                          headers={"Content-Type": "application/json"},
                          auth=(self.api_key, ''))

        if r.status_code == 200:
            return r.json()
        else:
            try:
                error = r.json()['error']
            except ValueError:
                error = r.text
            if r.status_code == 400:
                raise ScaleInvalidRequest(error, r.status_code)
            else:
                raise ScaleException(error, r.status_code)

    def fetch_task(self, task_id):
        """Fetches a task.

        Returns the associated task.
        """
        return Task(self._getrequest('task/%s' % task_id), self)

    def cancel_task(self, task_id):
        """Cancels a task.

        Returns the associated task.
        Raises a ScaleException if it has already been canceled.
        """
        return Task(self._postrequest('task/%s/cancel' % task_id), self)

    def tasks(self, **kwargs):
        """Returns a list of your tasks.
        Returns up to 100 at a time, to get more, use the next_token param passed back.

        Note that offset is deprecated.

        start/end_time are ISO8601 dates, the time range of tasks to fetch.
        status can be 'completed', 'pending', or 'canceled'.
        type is the task type.
        limit is the max number of results to display per page,
        next_token can be use to fetch the next page of tasks.
        offset (deprecated) is the number of results to skip (for showing more pages).
        """
        allowed_kwargs = {'start_time', 'end_time', 'status', 'type', 'project',
                          'batch', 'limit', 'offset', 'completed_before', 'completed_after',
                          'next_token'}
        for key in kwargs:
            if key not in allowed_kwargs:
                raise ScaleInvalidRequest('Illegal parameter %s for ScaleClient.tasks()'
                                          % key, None)
        response = self._getrequest('tasks', params=kwargs)
        docs = [Task(json, self) for json in response['docs']]
        return Tasklist(docs, response['total'], response['limit'],
                        response['offset'], response['has_more'], response.get('next_token'))
    def create_task(self, task_type, **kwargs):
        endpoint = 'task/' + task_type
        taskdata = self._postrequest(endpoint, payload=kwargs)
        return Task(taskdata, self)

def _AddTaskTypeCreator(task_type):
    def create_task_wrapper(self, **kwargs):
        return self.create_task(task_type, **kwargs)
    setattr(ScaleClient, 'create_' + task_type + '_task', create_task_wrapper)

for taskType in TASK_TYPES:
    _AddTaskTypeCreator(taskType)
<|endoftext|>


<commit_before>'''
Created on Mar 8,2015

@author: qiuyx
'''
from scan.commands.command import Command
import xml.etree.ElementTree as ET

class Set(Command):
    """Set a device to a value.

    With optional check of completion and readback verification.

    :param device:     Device name
    :param value:      Value
    :param completion: Await callback completion?
    :param readback:   `False` to not check any readback,
                       `True` to wait for readback from the `device`,
                       or name of specific device to check for readback.
    :param tolerance:  Tolerance when checking numeric `readback`.
    :param timeout:    Timeout in seconds, used for `completion` and `readback`.
    :param errhandler: Error handler

    Example:
        >>> cmd = Set('position', 10.5)

    """

    def __init__(self, device, value, completion=False, readback=False, tolerance=0.0, timeout=0.0, errhandler=None):
        self.__device=device
        self.__value=value
        self.__completion=completion
        self.__readback=readback
        self.__tolerance=tolerance
        self.__timeout=timeout
        self.__errHandler=errhandler

    def genXML(self):
        xml = ET.Element('set')

        dev=ET.SubElement(xml, 'device')
        if self.__device:
            dev.text = self.__device

        ET.SubElement(xml, 'value').text = str(self.__value)

        need_timeout = False
        if self.__completion:
            ET.SubElement(xml, 'completion').text = 'true'
            need_timeout = True

        if self.__readback:
            ET.SubElement(xml, "wait").text = "true"
            ET.SubElement(xml, "readback").text = self.__device if self.__readback == True else self.__readback
            ET.SubElement(xml, "tolerance").text = str(self.__tolerance)
            need_timeout = True
        if need_timeout  and  self.__timeout > 0:
            ET.SubElement(xml, "timeout").text = str(self.__timeout)

        if self.__errHandler:
            ET.SubElement(xml,'error_handler').text = self.__errHandler

        return xml

    def __repr__(self):
        return self.toCmdString()

    def toCmdString(self):
        result = "Set('%s'" % self.__device
        if isinstance(self.__value, str):
            result += ", '%s'" % self.__value
        else:
            result += ", %s" % str(self.__value)
        use_timeout = False
        if self.__completion:
            use_timeout = True
            result += ', completion=true'
        if isinstance(self.__readback, str):
            use_timeout = True
            result += ", readback='%s'" % self.__readback
        elif self.__readback:
            use_timeout = True
            result += ", readback=%s" % str(self.__readback)
        if use_timeout  and  self.__timeout!=0.0:
            result += ', timeOut='+str(self.__timeout)
        if self.__errHandler:
            result += ", errhandler='%s'" % self.__errHandler
        result+=')'
        return result

        <commit_msg>Set command repr fix: "True" instead of "true"<commit_after>'''
Created on Mar 8,2015

@author: qiuyx
'''
from scan.commands.command import Command
import xml.etree.ElementTree as ET

class Set(Command):
    """Set a device to a value.

    With optional check of completion and readback verification.

    :param device:     Device name
    :param value:      Value
    :param completion: Await callback completion?
    :param readback:   `False` to not check any readback,
                       `True` to wait for readback from the `device`,
                       or name of specific device to check for readback.
    :param tolerance:  Tolerance when checking numeric `readback`.
    :param timeout:    Timeout in seconds, used for `completion` and `readback`.
    :param errhandler: Error handler

    Example:
        >>> cmd = Set('position', 10.5)

    """

    def __init__(self, device, value, completion=False, readback=False, tolerance=0.0, timeout=0.0, errhandler=None):
        self.__device=device
        self.__value=value
        self.__completion=completion
        self.__readback=readback
        self.__tolerance=tolerance
        self.__timeout=timeout
        self.__errHandler=errhandler

    def genXML(self):
        xml = ET.Element('set')

        dev=ET.SubElement(xml, 'device')
        if self.__device:
            dev.text = self.__device

        ET.SubElement(xml, 'value').text = str(self.__value)

        need_timeout = False
        if self.__completion:
            ET.SubElement(xml, 'completion').text = 'true'
            need_timeout = True

        if self.__readback:
            ET.SubElement(xml, "wait").text = "true"
            ET.SubElement(xml, "readback").text = self.__device if self.__readback == True else self.__readback
            ET.SubElement(xml, "tolerance").text = str(self.__tolerance)
            need_timeout = True
        if need_timeout  and  self.__timeout > 0:
            ET.SubElement(xml, "timeout").text = str(self.__timeout)

        if self.__errHandler:
            ET.SubElement(xml,'error_handler').text = self.__errHandler

        return xml

    def __repr__(self):
        return self.toCmdString()

    def toCmdString(self):
        result = "Set('%s'" % self.__device
        if isinstance(self.__value, str):
            result += ", '%s'" % self.__value
        else:
            result += ", %s" % str(self.__value)
        use_timeout = False
        if self.__completion:
            use_timeout = True
            result += ', completion=True'
        if isinstance(self.__readback, str):
            use_timeout = True
            result += ", readback='%s'" % self.__readback
        elif self.__readback:
            use_timeout = True
            result += ", readback=%s" % str(self.__readback)
        if use_timeout  and  self.__timeout!=0.0:
            result += ', timeOut='+str(self.__timeout)
        if self.__errHandler:
            result += ", errhandler='%s'" % self.__errHandler
        result+=')'
        return result

        <|endoftext|>


<commit_before>import scarlett
from scarlett.constants import *
#from scarlett.errors import ProtocolError
#from IPython.core.debugger import Tracer

# Protocol specific constants
NULL_CHAR = '\x00'
MAGIC_RES_STRING = '%sRES' % NULL_CHAR
MAGIC_REQ_STRING = '%sREQ' % NULL_CHAR

# def get_command_name(cmd_type):
# return SCARLETT_COMMAND_TO_NAME.get(cmd_type, cmd_type)

class Command(object):

    def __init__(self, voice, brain, **kwargs):
        self.brain = brain
        self.config = scarlett.config
        self.voice = voice

    def check_cmd(self, command=''):

        if command in SPOTIFY_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'spotify %s'" %
                               (command, SPOTIFY_CMDS[command]))
            # REFACTOR ### spotify_play(SPOTIFY_CMDS[command])
        elif command in LIGHT_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'light %s'" %
                               (command, LIGHT_CMDS[command]))
            try:
                scarlett.log.debug(Fore.YELLOW + "trying light chit")
                self.get_hue = scarlett.connect_hue(self.voice, self.brain)
                return self.get_hue.get_light_names()
                # REFACTOR ### light_play(LIGHT_CMDS[command])
            except Exception as e:
                scarlett.log.debug(
                    Fore.YELLOW + "light exception b. \nCMD: %s \nException: %s" %
                    (command, e))
                # REFACTOR ### general_play("cancel")
        elif command in TIME_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'time %s'" %
                               (command, TIME_CMDS[command]))
            try:
                from scarlett.features.time import FeatureTime
                self.get_time = FeatureTime(self.voice, self.brain)
                return self.get_time.time_play()
            except Exception as e:
                scarlett.log.debug(
                    Fore.YELLOW + "time exception b. \nCMD: %s \nException: %s" %
                    (command, e))
                # return 1
                # REFACTOR ### general_play("cancel")
        elif command in GENERAL_CMDS.keys():
            scarlett.log.debug(
                Fore.YELLOW + "** received %s, sending 'general command: %s'" %
                (command, GENERAL_CMDS[command]))
            # REFACTOR ### general_play(GENERAL_CMDS[command])
        elif command in FORECAST_CMDS.keys():
            scarlett.log.debug(
                Fore.YELLOW + "** received %s, sending 'forecast command: %s'" %
                (command, FORECAST_CMDS[command]))
            # REFACTOR ### forecast_play(FORECAST_CMDS[command])
        elif command in TV_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'tv command: %s'" %
                               (command, TV_CMDS[command]))
            # REFACTOR ### tv_play(tv_commands[command])
<commit_msg>feature: initial commit for function that returns a class object based on a string<commit_after>import scarlett
from scarlett.constants import *
#from scarlett.errors import ProtocolError
#from IPython.core.debugger import Tracer

# Protocol specific constants
NULL_CHAR = '\x00'
MAGIC_RES_STRING = '%sRES' % NULL_CHAR
MAGIC_REQ_STRING = '%sREQ' % NULL_CHAR

# def get_command_name(cmd_type):
# return SCARLETT_COMMAND_TO_NAME.get(cmd_type, cmd_type)

# source: http://stackoverflow.com/questions/1176136/convert-string-to-python-class-object
# Convert string to Python class object?
import sys

# this returns a python class object based on its name
def str_to_class(str):
    return reduce(getattr, str.split("."), sys.modules[__name__])

class Command(object):

    def __init__(self, voice, brain, **kwargs):
        self.brain = brain
        self.config = scarlett.config
        self.voice = voice

    def check_cmd(self, command=''):

        if command in SPOTIFY_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'spotify %s'" %
                               (command, SPOTIFY_CMDS[command]))
            # REFACTOR ### spotify_play(SPOTIFY_CMDS[command])
        elif command in LIGHT_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'light %s'" %
                               (command, LIGHT_CMDS[command]))
            try:
                scarlett.log.debug(Fore.YELLOW + "trying light chit")
                self.get_hue = scarlett.connect_hue(self.voice, self.brain)
                return self.get_hue.get_light_names()
                # REFACTOR ### light_play(LIGHT_CMDS[command])
            except Exception as e:
                scarlett.log.debug(
                    Fore.YELLOW + "light exception b. \nCMD: %s \nException: %s" %
                    (command, e))
                # REFACTOR ### general_play("cancel")
        elif command in TIME_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'time %s'" %
                               (command, TIME_CMDS[command]))
            try:
                from scarlett.features.time import FeatureTime
                self.get_time = FeatureTime(self.voice, self.brain)
                return self.get_time.time_play()
            except Exception as e:
                scarlett.log.debug(
                    Fore.YELLOW + "time exception b. \nCMD: %s \nException: %s" %
                    (command, e))
                # return 1
                # REFACTOR ### general_play("cancel")
        elif command in GENERAL_CMDS.keys():
            scarlett.log.debug(
                Fore.YELLOW + "** received %s, sending 'general command: %s'" %
                (command, GENERAL_CMDS[command]))
            # REFACTOR ### general_play(GENERAL_CMDS[command])
        elif command in FORECAST_CMDS.keys():
            scarlett.log.debug(
                Fore.YELLOW + "** received %s, sending 'forecast command: %s'" %
                (command, FORECAST_CMDS[command]))
            # REFACTOR ### forecast_play(FORECAST_CMDS[command])
        elif command in TV_CMDS.keys():
            scarlett.log.debug(Fore.YELLOW +
                               "** received %s, sending 'tv command: %s'" %
                               (command, TV_CMDS[command]))
            # REFACTOR ### tv_play(tv_commands[command])
<|endoftext|>