<commit_before># encoding: utf-8
"""
A base class for objects that are configurable.

Authors:

* Brian Granger
* Fernando Perez
* Min RK
"""

#-----------------------------------------------------------------------------
#  Copyright (C) 2008-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

import datetime
from copy import deepcopy

from loader import Config
from IPython.utils.traitlets import HasTraits, Instance
from IPython.utils.text import indent, wrap_paragraphs

#-----------------------------------------------------------------------------
# Helper classes for Configurables
#-----------------------------------------------------------------------------

class ConfigurableError(Exception):
    pass

class MultipleInstanceError(ConfigurableError):
    pass

#-----------------------------------------------------------------------------
# Configurable implementation
#-----------------------------------------------------------------------------

class Configurable(HasTraits):

    config = Instance(Config,(),{})
    created = None

    def __init__(self, **kwargs):
        """Create a configurable given a config config.

        Parameters
        ----------
        config : Config
            If this is empty, default values are used. If config is a
            :class:`Config` instance, it will be used to configure the
            instance.

        Notes
        -----
        Subclasses of Configurable must call the :meth:`__init__` method of
        :class:`Configurable` *before* doing anything else and using
        :func:`super`::

            class MyConfigurable(Configurable):
                def __init__(self, config=None):
                    super(MyConfigurable, self).__init__(config)
                    # Then any other code you need to finish initialization.

        This ensures that instances will be configured properly.
        """
        config = kwargs.pop('config', None)
        if config is not None:
            # We used to deepcopy, but for now we are trying to just save
            # by reference.  This *could* have side effects as all components
            # will share config. In fact, I did find such a side effect in
            # _config_changed below. If a config attribute value was a mutable type
            # all instances of a component were getting the same copy, effectively
            # making that a class attribute.
            # self.config = deepcopy(config)
            self.config = config
        # This should go second so individual keyword arguments override
        # the values in config.
        super(Configurable, self).__init__(**kwargs)
        self.created = datetime.datetime.now()

    #-------------------------------------------------------------------------
    # Static trait notifiations
    #-------------------------------------------------------------------------

    def _config_changed(self, name, old, new):
        """Update all the class traits having ``config=True`` as metadata.

        For any class trait with a ``config`` metadata attribute that is
        ``True``, we update the trait with the value of the corresponding
        config entry.
        """
        # Get all traits with a config metadata entry that is True
        traits = self.traits(config=True)

        # We auto-load config section for this class as well as any parent
        # classes that are Configurable subclasses.  This starts with Configurable
        # and works down the mro loading the config for each section.
        section_names = [cls.__name__ for cls in \
            reversed(self.__class__.__mro__) if
            issubclass(cls, Configurable) and issubclass(self.__class__, cls)]

        for sname in section_names:
            # Don't do a blind getattr as that would cause the config to
            # dynamically create the section with name self.__class__.__name__.
            if new._has_section(sname):
                my_config = new[sname]
                for k, v in traits.iteritems():
                    # Don't allow traitlets with config=True to start with
                    # uppercase.  Otherwise, they are confused with Config
                    # subsections.  But, developers shouldn't have uppercase
                    # attributes anyways! (PEP 6)
                    if k[0].upper()==k[0] and not k.startswith('_'):
                        raise ConfigurableError('Configurable traitlets with '
                        'config=True must start with a lowercase so they are '
                        'not confused with Config subsections: %s.%s' % \
                        (self.__class__.__name__, k))
                    try:
                        # Here we grab the value from the config
                        # If k has the naming convention of a config
                        # section, it will be auto created.
                        config_value = my_config[k]
                    except KeyError:
                        pass
                    else:
                        # print "Setting %s.%s from %s.%s=%r" % \
                        #     (self.__class__.__name__,k,sname,k,config_value)
                        # We have to do a deepcopy here if we don't deepcopy the entire
                        # config object. If we don't, a mutable config_value will be
                        # shared by all instances, effectively making it a class attribute.
                        setattr(self, k, deepcopy(config_value))

    @classmethod
    def class_get_help(cls):
        """Get the help string for this class in ReST format."""
        cls_traits = cls.class_traits(config=True)
        final_help = []
        final_help.append(u'%s options' % cls.__name__)
        final_help.append(len(final_help[0])*u'-')
        for k,v in cls.class_traits(config=True).iteritems():
            help = cls.class_get_trait_help(v)
            final_help.append(help)
        return '\n'.join(final_help)

    @classmethod
    def class_get_trait_help(cls, trait):
        """Get the help string for a single trait."""
        lines = []
        header = "--%s.%s=<%s>" % (cls.__name__, trait.name, trait.__class__.__name__)
        lines.append(header)
        try:
            dvr = repr(trait.get_default_value())
        except Exception:
            dvr = None # ignore defaults we can't construct
        if dvr is not None:
            if len(dvr) > 64:
                dvr = dvr[:61]+'...'
            lines.append(indent('Default: %s'%dvr, 4))
        if 'Enum' in trait.__class__.__name__:
            # include Enum choices
            lines.append(indent('Choices: %r'%(trait.values,)))

        help = trait.get_metadata('help')
        if help is not None:
            help = '\n'.join(wrap_paragraphs(help, 76))
            lines.append(indent(help, 4))
        return '\n'.join(lines)

    @classmethod
    def class_print_help(cls):
        """Get the help string for a single trait and print it."""
        print cls.class_get_help()

    @classmethod
    def class_config_section(cls):
        """Get the config class config section"""
        def c(s):
            """return a commented, wrapped block."""
            s = '\n\n'.join(wrap_paragraphs(s, 78))

            return '# ' + s.replace('\n', '\n# ')

        # section header
        breaker = '#' + '-'*78
        s = "# %s configuration"%cls.__name__
        lines = [breaker, s, breaker, '']
        # get the description trait
        desc = cls.class_traits().get('description')
        if desc:
            desc = desc.default_value
        else:
            # no description trait, use __doc__
            desc = getattr(cls, '__doc__', '')
        if desc:
            lines.append(c(desc))
            lines.append('')

        parents = []
        for parent in cls.mro():
            # only include parents that are not base classes
            # and are not the class itself
            # and have some configurable traits to inherit
            if parent is not cls and issubclass(parent, Configurable) and \
                    parent.class_traits(config=True):
                parents.append(parent)

        if parents:
            pstr = ', '.join([ p.__name__ for p in parents ])
            lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
            lines.append('')

        for name,trait in cls.class_traits(config=True).iteritems():
            help = trait.get_metadata('help') or ''
            lines.append(c(help))
            lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
            lines.append('')
        return '\n'.join(lines)

class SingletonConfigurable(Configurable):
    """A configurable that only allows one instance.

    This class is for classes that should only have one instance of itself
    or *any* subclass. To create and retrieve such a class use the
    :meth:`SingletonConfigurable.instance` method.
    """

    _instance = None

    @classmethod
    def _walk_mro(cls):
        """Walk the cls.mro() for parent classes that are also singletons

        For use in instance()
        """

        for subclass in cls.mro():
            if issubclass(cls, subclass) and \
                    issubclass(subclass, SingletonConfigurable) and \
                    subclass != SingletonConfigurable:
                yield subclass

    @classmethod
    def clear_instance(cls):
        """unset _instance for this class and singleton parents.
        """
        if not cls.initialized():
            return
        for subclass in cls._walk_mro():
            if isinstance(subclass._instance, cls):
                # only clear instances that are instances
                # of the calling class
                subclass._instance = None

    @classmethod
    def instance(cls, *args, **kwargs):
        """Returns a global instance of this class.

        This method create a new instance if none have previously been created
        and returns a previously created instance is one already exists.

        The arguments and keyword arguments passed to this method are passed
        on to the :meth:`__init__` method of the class upon instantiation.

        Examples
        --------

        Create a singleton class using instance, and retrieve it::

            >>> from IPython.config.configurable import SingletonConfigurable
            >>> class Foo(SingletonConfigurable): pass
            >>> foo = Foo.instance()
            >>> foo == Foo.instance()
            True

        Create a subclass that is retrived using the base class instance::

            >>> class Bar(SingletonConfigurable): pass
            >>> class Bam(Bar): pass
            >>> bam = Bam.instance()
            >>> bam == Bar.instance()
            True
        """
        # Create and save the instance
        if cls._instance is None:
            inst = cls(*args, **kwargs)
            # Now make sure that the instance will also be returned by
            # parent classes' _instance attribute.
            for subclass in cls._walk_mro():
                subclass._instance = inst

        if isinstance(cls._instance, cls):
            return cls._instance
        else:
            raise MultipleInstanceError(
                'Multiple incompatible subclass instances of '
                '%s are being created.' % cls.__name__
            )

    @classmethod
    def initialized(cls):
        """Has an instance been created?"""
        return hasattr(cls, "_instance") and cls._instance is not None

class LoggingConfigurable(Configurable):
    """A parent class for Configurables that log.

    Subclasses have a log trait, and the default behavior
    is to get the logger from the currently running Application
    via Application.instance().log.
    """

    log = Instance('logging.Logger')
    def _log_default(self):
        from IPython.config.application import Application
        return Application.instance().log

<commit_msg>move useful update_config method to Configurable from Application<commit_after># encoding: utf-8
"""
A base class for objects that are configurable.

Authors:

* Brian Granger
* Fernando Perez
* Min RK
"""

#-----------------------------------------------------------------------------
#  Copyright (C) 2008-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

import datetime
from copy import deepcopy

from loader import Config
from IPython.utils.traitlets import HasTraits, Instance
from IPython.utils.text import indent, wrap_paragraphs

#-----------------------------------------------------------------------------
# Helper classes for Configurables
#-----------------------------------------------------------------------------

class ConfigurableError(Exception):
    pass

class MultipleInstanceError(ConfigurableError):
    pass

#-----------------------------------------------------------------------------
# Configurable implementation
#-----------------------------------------------------------------------------

class Configurable(HasTraits):

    config = Instance(Config,(),{})
    created = None

    def __init__(self, **kwargs):
        """Create a configurable given a config config.

        Parameters
        ----------
        config : Config
            If this is empty, default values are used. If config is a
            :class:`Config` instance, it will be used to configure the
            instance.

        Notes
        -----
        Subclasses of Configurable must call the :meth:`__init__` method of
        :class:`Configurable` *before* doing anything else and using
        :func:`super`::

            class MyConfigurable(Configurable):
                def __init__(self, config=None):
                    super(MyConfigurable, self).__init__(config)
                    # Then any other code you need to finish initialization.

        This ensures that instances will be configured properly.
        """
        config = kwargs.pop('config', None)
        if config is not None:
            # We used to deepcopy, but for now we are trying to just save
            # by reference.  This *could* have side effects as all components
            # will share config. In fact, I did find such a side effect in
            # _config_changed below. If a config attribute value was a mutable type
            # all instances of a component were getting the same copy, effectively
            # making that a class attribute.
            # self.config = deepcopy(config)
            self.config = config
        # This should go second so individual keyword arguments override
        # the values in config.
        super(Configurable, self).__init__(**kwargs)
        self.created = datetime.datetime.now()

    #-------------------------------------------------------------------------
    # Static trait notifiations
    #-------------------------------------------------------------------------

    def _config_changed(self, name, old, new):
        """Update all the class traits having ``config=True`` as metadata.

        For any class trait with a ``config`` metadata attribute that is
        ``True``, we update the trait with the value of the corresponding
        config entry.
        """
        # Get all traits with a config metadata entry that is True
        traits = self.traits(config=True)

        # We auto-load config section for this class as well as any parent
        # classes that are Configurable subclasses.  This starts with Configurable
        # and works down the mro loading the config for each section.
        section_names = [cls.__name__ for cls in \
            reversed(self.__class__.__mro__) if
            issubclass(cls, Configurable) and issubclass(self.__class__, cls)]

        for sname in section_names:
            # Don't do a blind getattr as that would cause the config to
            # dynamically create the section with name self.__class__.__name__.
            if new._has_section(sname):
                my_config = new[sname]
                for k, v in traits.iteritems():
                    # Don't allow traitlets with config=True to start with
                    # uppercase.  Otherwise, they are confused with Config
                    # subsections.  But, developers shouldn't have uppercase
                    # attributes anyways! (PEP 6)
                    if k[0].upper()==k[0] and not k.startswith('_'):
                        raise ConfigurableError('Configurable traitlets with '
                        'config=True must start with a lowercase so they are '
                        'not confused with Config subsections: %s.%s' % \
                        (self.__class__.__name__, k))
                    try:
                        # Here we grab the value from the config
                        # If k has the naming convention of a config
                        # section, it will be auto created.
                        config_value = my_config[k]
                    except KeyError:
                        pass
                    else:
                        # print "Setting %s.%s from %s.%s=%r" % \
                        #     (self.__class__.__name__,k,sname,k,config_value)
                        # We have to do a deepcopy here if we don't deepcopy the entire
                        # config object. If we don't, a mutable config_value will be
                        # shared by all instances, effectively making it a class attribute.
                        setattr(self, k, deepcopy(config_value))

    def update_config(self, config):
        """Fire the traits events when the config is updated."""
        # Save a copy of the current config.
        newconfig = deepcopy(self.config)
        # Merge the new config into the current one.
        newconfig._merge(config)
        # Save the combined config as self.config, which triggers the traits
        # events.
        self.config = newconfig

    @classmethod
    def class_get_help(cls):
        """Get the help string for this class in ReST format."""
        cls_traits = cls.class_traits(config=True)
        final_help = []
        final_help.append(u'%s options' % cls.__name__)
        final_help.append(len(final_help[0])*u'-')
        for k,v in cls.class_traits(config=True).iteritems():
            help = cls.class_get_trait_help(v)
            final_help.append(help)
        return '\n'.join(final_help)

    @classmethod
    def class_get_trait_help(cls, trait):
        """Get the help string for a single trait."""
        lines = []
        header = "--%s.%s=<%s>" % (cls.__name__, trait.name, trait.__class__.__name__)
        lines.append(header)
        try:
            dvr = repr(trait.get_default_value())
        except Exception:
            dvr = None # ignore defaults we can't construct
        if dvr is not None:
            if len(dvr) > 64:
                dvr = dvr[:61]+'...'
            lines.append(indent('Default: %s'%dvr, 4))
        if 'Enum' in trait.__class__.__name__:
            # include Enum choices
            lines.append(indent('Choices: %r'%(trait.values,)))

        help = trait.get_metadata('help')
        if help is not None:
            help = '\n'.join(wrap_paragraphs(help, 76))
            lines.append(indent(help, 4))
        return '\n'.join(lines)

    @classmethod
    def class_print_help(cls):
        """Get the help string for a single trait and print it."""
        print cls.class_get_help()

    @classmethod
    def class_config_section(cls):
        """Get the config class config section"""
        def c(s):
            """return a commented, wrapped block."""
            s = '\n\n'.join(wrap_paragraphs(s, 78))

            return '# ' + s.replace('\n', '\n# ')

        # section header
        breaker = '#' + '-'*78
        s = "# %s configuration"%cls.__name__
        lines = [breaker, s, breaker, '']
        # get the description trait
        desc = cls.class_traits().get('description')
        if desc:
            desc = desc.default_value
        else:
            # no description trait, use __doc__
            desc = getattr(cls, '__doc__', '')
        if desc:
            lines.append(c(desc))
            lines.append('')

        parents = []
        for parent in cls.mro():
            # only include parents that are not base classes
            # and are not the class itself
            # and have some configurable traits to inherit
            if parent is not cls and issubclass(parent, Configurable) and \
                    parent.class_traits(config=True):
                parents.append(parent)

        if parents:
            pstr = ', '.join([ p.__name__ for p in parents ])
            lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
            lines.append('')

        for name,trait in cls.class_traits(config=True).iteritems():
            help = trait.get_metadata('help') or ''
            lines.append(c(help))
            lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
            lines.append('')
        return '\n'.join(lines)

class SingletonConfigurable(Configurable):
    """A configurable that only allows one instance.

    This class is for classes that should only have one instance of itself
    or *any* subclass. To create and retrieve such a class use the
    :meth:`SingletonConfigurable.instance` method.
    """

    _instance = None

    @classmethod
    def _walk_mro(cls):
        """Walk the cls.mro() for parent classes that are also singletons

        For use in instance()
        """

        for subclass in cls.mro():
            if issubclass(cls, subclass) and \
                    issubclass(subclass, SingletonConfigurable) and \
                    subclass != SingletonConfigurable:
                yield subclass

    @classmethod
    def clear_instance(cls):
        """unset _instance for this class and singleton parents.
        """
        if not cls.initialized():
            return
        for subclass in cls._walk_mro():
            if isinstance(subclass._instance, cls):
                # only clear instances that are instances
                # of the calling class
                subclass._instance = None

    @classmethod
    def instance(cls, *args, **kwargs):
        """Returns a global instance of this class.

        This method create a new instance if none have previously been created
        and returns a previously created instance is one already exists.

        The arguments and keyword arguments passed to this method are passed
        on to the :meth:`__init__` method of the class upon instantiation.

        Examples
        --------

        Create a singleton class using instance, and retrieve it::

            >>> from IPython.config.configurable import SingletonConfigurable
            >>> class Foo(SingletonConfigurable): pass
            >>> foo = Foo.instance()
            >>> foo == Foo.instance()
            True

        Create a subclass that is retrived using the base class instance::

            >>> class Bar(SingletonConfigurable): pass
            >>> class Bam(Bar): pass
            >>> bam = Bam.instance()
            >>> bam == Bar.instance()
            True
        """
        # Create and save the instance
        if cls._instance is None:
            inst = cls(*args, **kwargs)
            # Now make sure that the instance will also be returned by
            # parent classes' _instance attribute.
            for subclass in cls._walk_mro():
                subclass._instance = inst

        if isinstance(cls._instance, cls):
            return cls._instance
        else:
            raise MultipleInstanceError(
                'Multiple incompatible subclass instances of '
                '%s are being created.' % cls.__name__
            )

    @classmethod
    def initialized(cls):
        """Has an instance been created?"""
        return hasattr(cls, "_instance") and cls._instance is not None

class LoggingConfigurable(Configurable):
    """A parent class for Configurables that log.

    Subclasses have a log trait, and the default behavior
    is to get the logger from the currently running Application
    via Application.instance().log.
    """

    log = Instance('logging.Logger')
    def _log_default(self):
        from IPython.config.application import Application
        return Application.instance().log

<|endoftext|>


<commit_before>#!/usr/bin/python3

from __init__ import *
from pprint import pprint

# create device instance
base_station = eNB()
relays = [RN() for i in range(6)]
users = [UE() for i in range(240)]

# assign the relationship and CQI
base_station.childs = relays
for i in range(len(relays)):
	relays[i].childs = users[i*40:i*40+40]
	relays[i].parent = base_station
	relays[i].CQI = ['H']
	for j in range(i*40, i*40+40):
		users[j].parent = relays[i]
		users[j].CQI = ['M', 'H']

# build up the bearer from parent to child
for i in base_station.childs:
	base_station.connect(i, status='D', interface='backhaul', bandwidth=BANDWIDTH, flow='VoIP')
	for j in i.childs:
		i.connect(j, status='D', interface='access', bandwidth=BANDWIDTH, flow='VoIP')

# decide 2-hop TDD configuration (fixed)

# calc pre-inter-arrival-time of packets (encapsulate)
simulation_time = 10
timeline = { i:[] for i in range(simulation_time+1)}
UE_lambda = [i.lambd for i in users]

for i in range(len(users)):

	for bearer in users[i].link['access']:
		arrTimeByBearer = [0]

		# random process of getting inter-arrival-time by bearer
		while arrTimeByBearer[-1]<=simulation_time:
			arrTimeByBearer.append(arrTimeByBearer[-1]+random.expovariate(users[i].lambd['access']))
		arrTimeByBearer[-1] > simulation_time and arrTimeByBearer.pop()
		arrTimeByBearer.pop(0)

		# assign pkt to real timeline
		for arrTime in range(len(arrTimeByBearer)):
			pkt = {
				'device': users[i],
				'flow': bearer.flow,
				'delay_budget': traffic[bearer.flow]['delay_budget'],
				'bitrate': traffic[bearer.flow]['bitrate'],
				'arrival_time': arrTimeByBearer[arrTime]
			}
			timeline[math.ceil(pkt['arrival_time'])].append(pkt)

for i in range(len(timeline)):
	timeline[i] = sorted(timeline[i], key=lambda x: x['arrival_time'])

msg_success("==========\tsimulation start\t==========")
discard_pkt = []
TTI = 1
print(base_station.capacity)
while TTI != simulation_time+1:

	# check the arrival pkt from internet
	if not timeline[TTI]:
		TTI += 1
		continue

	# discard timeout pkt and record
	for child in base_station.queue['backhaul']:
		for pkt in base_station.queue['backhaul'][child]:
			if TTI - pkt['arrival_time'] > pkt['delay_budget']:
				base_station.queue['backhaul'][child].remove(pkt)
				discard_pkt.append(pkt)

	# DeNB receive pkt from internet and classified
	for arrPkt in timeline[TTI]:
		base_station.queue['backhaul'][arrPkt['device'].parent.name].append(arrPkt)

	# check the sleep mode for each mode (apply LBPS)

	# transmission scheduling: 2-hop FIFO

	TTI += 1

msg_success("==========\tsimulation end\t\t==========")
<commit_msg>add: TDD configuration decision<commit_after>#!/usr/bin/python3

from __init__ import *
from pprint import pprint

# create device instance
base_station = eNB()
relays = [RN() for i in range(6)]
users = [UE() for i in range(240)]

# assign the relationship and CQI
base_station.childs = relays
for i in range(len(relays)):
	relays[i].childs = users[i*40:i*40+40]
	relays[i].parent = base_station
	relays[i].CQI = ['H']
	for j in range(i*40, i*40+40):
		users[j].parent = relays[i]
		users[j].CQI = ['M', 'H']

# build up the bearer from parent to child
for i in base_station.childs:
	base_station.connect(i, status='D', interface='backhaul', bandwidth=BANDWIDTH, flow='VoIP')
	for j in i.childs:
		i.connect(j, status='D', interface='access', bandwidth=BANDWIDTH, flow='VoIP')

# calc pre-inter-arrival-time of packets (encapsulate)
simulation_time = 10
timeline = { i:[] for i in range(simulation_time+1)}
UE_lambda = [i.lambd for i in users]

for i in range(len(users)):

	for bearer in users[i].link['access']:
		arrTimeByBearer = [0]

		# random process of getting inter-arrival-time by bearer
		while arrTimeByBearer[-1]<=simulation_time:
			arrTimeByBearer.append(arrTimeByBearer[-1]+random.expovariate(users[i].lambd['access']))
		arrTimeByBearer[-1] > simulation_time and arrTimeByBearer.pop()
		arrTimeByBearer.pop(0)

		# assign pkt to real timeline
		for arrTime in range(len(arrTimeByBearer)):
			pkt = {
				'device': users[i],
				'flow': bearer.flow,
				'delay_budget': traffic[bearer.flow]['delay_budget'],
				'bitrate': traffic[bearer.flow]['bitrate'],
				'arrival_time': arrTimeByBearer[arrTime]
			}
			timeline[math.ceil(pkt['arrival_time'])].append(pkt)

for i in range(len(timeline)):
	timeline[i] = sorted(timeline[i], key=lambda x: x['arrival_time'])

# decide 2-hop TDD configuration (DL)(fixed)
candidate = TWO_HOP_TDD_CONFIG.copy()
pprint(candidate)
radio_frame_pkt = [pkt for TTI in timeline for pkt in timeline[TTI] if TTI <= 10]
total_pktSize = sum([traffic[pkt['flow']]['pkt_size'] for pkt in radio_frame_pkt])

# backhaul and access filter for TDD configuration decision
n_b_subframe = math.ceil(total_pktSize / base_station.capacity)
candidate = {i: candidate[i] for i in candidate if candidate[i]['backhaul'].count('D') >= n_b_subframe}
n_a_subframe = [math.ceil(total_pktSize/len(base_station.childs)/i.capacity['access']) for i in base_station.childs]
candidate = {i: candidate[i] for i in candidate if candidate[i]['access'].count('D') >= max(n_a_subframe)}

msg_success("==========\tsimulation start\t==========")
TDD_CONFIG = random.choice(candidate)
discard_pkt = []
TTI = 1

while TTI != simulation_time+1:

	# check the arrival pkt from internet
	if not timeline[TTI]:
		TTI += 1
		continue

	# discard timeout pkt and record
	for child in base_station.queue['backhaul']:
		for pkt in base_station.queue['backhaul'][child]:
			if TTI - pkt['arrival_time'] > pkt['delay_budget']:
				base_station.queue['backhaul'][child].remove(pkt)
				discard_pkt.append(pkt)

	# DeNB receive pkt from internet and classified
	for arrPkt in timeline[TTI]:
		base_station.queue['backhaul'][arrPkt['device'].parent.name].append(arrPkt)

	# check the sleep mode for each mode (apply LBPS)

	# transmission scheduling: 2-hop FIFO

	TTI += 1

msg_success("==========\tsimulation end\t\t==========")
<|endoftext|>


<commit_before>"""Simple magics for display formats"""
#-----------------------------------------------------------------------------
#  Copyright (c) 2012 The IPython Development Team.
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Our own packages
from IPython.core.display import display, Javascript, Latex, SVG, HTML
from IPython.core.magic import  (
    Magics, magics_class, cell_magic
)

#-----------------------------------------------------------------------------
# Magic implementation classes
#-----------------------------------------------------------------------------

@magics_class
class DisplayMagics(Magics):
    """Magics for displaying various output types with literals

    Defines javascript/latex/svg/html cell magics for writing
    blocks in those languages, to be rendered in the frontend.
    """

    @cell_magic
    def javascript(self, line, cell):
        """Run the cell block of Javascript code"""
        display(Javascript(cell))

    @cell_magic
    def latex(self, line, cell):
        """Render the cell as a block of latex

        This magic only renders the subset of latex defined by MathJax
        [here](https://docs.mathjax.org/en/v2.5-latest/tex.html)."""
        display(Latex(cell))

    @cell_magic
    def svg(self, line, cell):
        """Render the cell as an SVG literal"""
        display(SVG(cell))

    @cell_magic
    def html(self, line, cell):
        """Render the cell as a block of HTML"""
        display(HTML(cell))
<commit_msg>Clarify that the MathJax comment is Notebook specific.<commit_after>"""Simple magics for display formats"""
#-----------------------------------------------------------------------------
#  Copyright (c) 2012 The IPython Development Team.
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Our own packages
from IPython.core.display import display, Javascript, Latex, SVG, HTML
from IPython.core.magic import  (
    Magics, magics_class, cell_magic
)

#-----------------------------------------------------------------------------
# Magic implementation classes
#-----------------------------------------------------------------------------

@magics_class
class DisplayMagics(Magics):
    """Magics for displaying various output types with literals

    Defines javascript/latex/svg/html cell magics for writing
    blocks in those languages, to be rendered in the frontend.
    """

    @cell_magic
    def javascript(self, line, cell):
        """Run the cell block of Javascript code"""
        display(Javascript(cell))

    @cell_magic
    def latex(self, line, cell):
        """Render the cell as a block of latex

        The subset of latex which is support depends on the implementation in
        the client.  In the Jupyter Notebook, this magic only renders the subset
        of latex defined by MathJax
        [here](https://docs.mathjax.org/en/v2.5-latest/tex.html)."""
        display(Latex(cell))

    @cell_magic
    def svg(self, line, cell):
        """Render the cell as an SVG literal"""
        display(SVG(cell))

    @cell_magic
    def html(self, line, cell):
        """Render the cell as a block of HTML"""
        display(HTML(cell))
<|endoftext|>


<commit_before>#coding=utf-8

# Published 2016
# Author : sebastien at pittet dot org
# Public domain source code, under MIT License

"""
This API provides access to Cave-Link data. It has some interest for cavers.
Following libraries are required :
    $ pip install python-dateutil
"""

from dateutil.parser import *
import time
import re # to use regular expression in python

# HTTP libraries depends upon Python 2 or 3
from sys import version_info
if version_info.major == 3 :
    import urllib.parse, urllib.request
else:
    import urllib2

print(version_info.major)

########################### Common definitions #########################
# Some examples of URL
_CL_NIVEAU_S2_COVA = "http://www.cavelink.com/cl/da.php?s=115&g=1&w=103&l=10"
_CL_NIVEAU_LANCELEAU = "http://www.cavelink.com/cl/da.php?s=142&g=20&w=100&l=10"
_CL_TEMP_SIPHON = "http://www.cavelink.com/cl/da.php?s=106&g=1&w=0&l=10"
_CL_V_FEES_SUR1 = "http://www.cavelink.com/cl/da.php?s=142&g=0&w=0&l=10"
_CL_TEMP_FEES_SUR1 = "http://www.cavelink.com/cl/da.php?s=142&g=10&w=1&l=10"

# Default definitions
default_CL = _CL_NIVEAU_LANCELEAU
default_rows = '10'

#########################################################################

class Cavelink:
    """
    Parse the webpage used to export the data and
    provides values back.
    """

    def __init__(self, URL = default_CL, rows = default_rows):
        # Replace number of rows, if provided
        URL = re.sub( '(?<=l=)\d{1,}', str(rows), URL )

        webpage = urllib2.Request(URL)

        try:
            handle = urllib2.urlopen(webpage)
        except IOError:
            print ('ERROR : unable to get the webpage :-/')

        # Get the HTML page
        htmlContent = handle.read()

        self.rawData = htmlContent.replace(",", "") # remove the separator (comma)
        self.data = htmlContent.split("
")

        for line in self.data:

            match = re.search('(?<=Stn=)\d{1,}', line)
            if match:
                self.station = match.group(0)

            match = re.search('(?<=Grp=)\d{1,}', line)
            if match:
                self.group = match.group(0)

            match = re.search('(?<=Nr=)\d{1,}', line)
            if match:
                self.number = match.group(0)

            match = re.search('(?<=Einheit : )\w{1,}', line)
            if match:
                self.unit = match.group(0).upper() # uppercase (C | M | ?)

    @property

    def station(self):
        return self.station

    def group(self):
        return self.group

    def number(self):
        return self.number

    def unit(self):
        return self.unit

    def getData(self):
        DictValues = {}

        for line in self.data:
            if IsNotNull(line):
                epochDatetime = findDate(line[0:16])
                if epochDatetime > 0:
                    # a date was found on this line
                    DictValues [epochDatetime] = float(line[17:]) # Create a dict with values
        return DictValues

####################### SOME USEFUL TOOLS ###############################
def IsNotNull(value):
    return value is not None and len(value) > 0

def toEpoch(value):
    return int( time.mktime(time.strptime(value,"%Y-%m-%d %H:%M:%S")) )

def findDate(inputValue):
    try:
        DateTimeString = str( parse(inputValue, ignoretz=True, dayfirst=True) )
    except:
        #if not found, epoch = 0
        DateTimeString = "1970-01-01 00:00:00"

    # Convert to epoch date time and return the value
    return toEpoch(DateTimeString)

def toHumanTime(epoch):
    return time.strftime("%d.%m.%Y %H:%M", time.localtime(float(epoch)))
######################################################################

# auto-test when executed directly

if __name__ == "__main__":

    from sys import exit, stdout, stderr

    # If launched interactively, display OK message
    if stdout.isatty():
        # Get last value measured/transmitted (by asking only 1 last row)
        SlumpTemperature = Cavelink(URL=_CL_TEMP_SIPHON, rows=10)
        Data = SlumpTemperature.getData()

        print('################################################')
        print('Station ID is: %s' % SlumpTemperature.station )
        print('Group ID is: %s' % SlumpTemperature.group )
        print('Number is: %s' % SlumpTemperature.number )
        print('Unit for this data set is: %s\n---' % SlumpTemperature.unit )

        for key, value in Data.iteritems():
            LastDataValue = value
            LastDataTime = toHumanTime(str(key))
            print('%s : %s %s' % (LastDataTime, LastDataValue, SlumpTemperature.unit))

        print('################################################')

    exit(0)
<commit_msg>try to get code compatible with python3<commit_after>#coding=utf-8

# Published 2016
# Author : sebastien at pittet dot org
# Public domain source code, under MIT License

"""
This API provides access to Cave-Link data. It has some interest for cavers.
Following libraries are required :
    $ pip install python-dateutil
"""

from dateutil.parser import *
import time
import re # to use regular expression in python

# HTTP libraries depends upon Python 2 or 3
from sys import version_info
if version_info.major == 3 :
    import urllib.request
else:
    import urllib2

########################### Common definitions #########################
# Some examples of URL
_CL_NIVEAU_S2_COVA = "http://www.cavelink.com/cl/da.php?s=115&g=1&w=103&l=10"
_CL_NIVEAU_LANCELEAU = "http://www.cavelink.com/cl/da.php?s=142&g=20&w=100&l=10"
_CL_TEMP_SIPHON = "http://www.cavelink.com/cl/da.php?s=106&g=1&w=0&l=10"
_CL_V_FEES_SUR1 = "http://www.cavelink.com/cl/da.php?s=142&g=0&w=0&l=10"
_CL_TEMP_FEES_SUR1 = "http://www.cavelink.com/cl/da.php?s=142&g=10&w=1&l=10"

# Default definitions
default_CL = _CL_NIVEAU_LANCELEAU
default_rows = '10'

#########################################################################

class Cavelink:
    """
    Parse the webpage used to export the data and
    provides values back.
    """

    def __init__(self, URL = default_CL, rows = default_rows):
        # Replace number of rows, if provided
        URL = re.sub( '(?<=l=)\d{1,}', str(rows), URL )

        htmlContent = ReadWebPage(URL)

        self.rawData = htmlContent.replace(",", "") # remove the separator (comma)
        self.data = htmlContent.split("
")

        for line in self.data:

            match = re.search('(?<=Stn=)\d{1,}', line)
            if match:
                self.station = match.group(0)

            match = re.search('(?<=Grp=)\d{1,}', line)
            if match:
                self.group = match.group(0)

            match = re.search('(?<=Nr=)\d{1,}', line)
            if match:
                self.number = match.group(0)

            match = re.search('(?<=Einheit : )\w{1,}', line)
            if match:
                self.unit = match.group(0).upper() # uppercase (C | M | ?)

    @property

    def station(self):
        return self.station

    def group(self):
        return self.group

    def number(self):
        return self.number

    def unit(self):
        return self.unit

    def getData(self):
        DictValues = {}

        for line in self.data:
            if IsNotNull(line):
                epochDatetime = findDate(line[0:16])
                if epochDatetime > 0:
                    # a date was found on this line
                    DictValues [epochDatetime] = float(line[17:]) # Create a dict with values
        return DictValues

####################### SOME USEFUL TOOLS ###############################
def IsNotNull(value):
    return value is not None and len(value) > 0

def toEpoch(value):
    return int( time.mktime(time.strptime(value,"%Y-%m-%d %H:%M:%S")) )

def findDate(inputValue):
    try:
        DateTimeString = str( parse(inputValue, ignoretz=True, dayfirst=True) )
    except:
        #if not found, epoch = 0
        DateTimeString = "1970-01-01 00:00:00"

    # Convert to epoch date time and return the value
    return toEpoch(DateTimeString)

def toHumanTime(epoch):
    return time.strftime("%d.%m.%Y %H:%M", time.localtime(float(epoch)))

def ReadWebPage(URL):
    # HTTP libraries depends upon Python 2 or 3
    from sys import version_info
    if version_info.major == 3 :
        import urllib.request
        webpage = urllib.request(URL)

        try:
            handle = urllib.urlopen(webpage)
        except IOError:
            print ('ERROR : unable to get the webpage :-/')
    else:
        import urllib2
        webpage = urllib2.Request(URL)

        try:
            handle = urllib2.urlopen(webpage)
        except IOError:
            print ('ERROR : unable to get the webpage :-/')

        # Get the HTML page
        htmlContent = handle.read()

    return htmlContent
######################################################################

# auto-test when executed directly

if __name__ == "__main__":

    from sys import exit, stdout, stderr

    # If launched interactively, display OK message
    if stdout.isatty():
        # Get last value measured/transmitted (by asking only 1 last row)
        SlumpTemperature = Cavelink(URL=_CL_TEMP_SIPHON, rows=10)
        Data = SlumpTemperature.getData()

        print('################################################')
        print('Station ID is: %s' % SlumpTemperature.station )
        print('Group ID is: %s' % SlumpTemperature.group )
        print('Number is: %s' % SlumpTemperature.number )
        print('Unit for this data set is: %s\n---' % SlumpTemperature.unit )

        for key, value in Data.iteritems():
            LastDataValue = value
            LastDataTime = toHumanTime(str(key))
            print('%s : %s %s' % (LastDataTime, LastDataValue, SlumpTemperature.unit))

        print('################################################')

    exit(0)
<|endoftext|>


<commit_before>""" Version information for InvenTree.
Provides information on the current InvenTree version
"""

import subprocess
import django
import re

import common.models

INVENTREE_SW_VERSION = "0.2.4 pre"

INVENTREE_API_VERSION = 6

"""
Increment thi API version number whenever there is a significant change to the API that any clients need to know about

v6 -> 2021-06-23
    - Part and Company images can now be directly uploaded via the REST API

v5 -> 2021-06-21
    - Adds API interface for manufacturer part parameters

v4 -> 2021-06-01
    - BOM items can now accept "variant stock" to be assigned against them
    - Many slight API tweaks were needed to get this to work properly!

v3 -> 2021-05-22:
    - The updated StockItem "history tracking" now uses a different interface

"""

def inventreeInstanceName():
    """ Returns the InstanceName settings for the current database """
    return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")

def inventreeInstanceTitle():
    """ Returns the InstanceTitle for the current database """
    if common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE_TITLE", False):
        return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")
    else:
        return 'InvenTree'

def inventreeVersion():
    """ Returns the InvenTree version string """
    return INVENTREE_SW_VERSION

def inventreeVersionTuple(version=None):
    """ Return the InvenTree version string as (maj, min, sub) tuple """

    if version is None:
        version = INVENTREE_SW_VERSION

    match = re.match(r"^.*(\d+)\.(\d+)\.(\d+).*$", str(version))

    return [int(g) for g in match.groups()]

def isInvenTreeUpToDate():
    """
    Test if the InvenTree instance is "up to date" with the latest version.

    A background task periodically queries GitHub for latest version,
    and stores it to the database as INVENTREE_LATEST_VERSION
    """

    latest = common.models.InvenTreeSetting.get_setting('INVENTREE_LATEST_VERSION', None)

    # No record for "latest" version - we must assume we are up to date!
    if not latest:
        return True

    # Extract "tuple" version (Python can directly compare version tuples)
    latest_version = inventreeVersionTuple(latest)
    inventree_version = inventreeVersionTuple()

    return inventree_version >= latest_version

def inventreeApiVersion():
    return INVENTREE_API_VERSION

def inventreeDjangoVersion():
    """ Return the version of Django library """
    return django.get_version()

def inventreeCommitHash():
    """ Returns the git commit hash for the running codebase """

    try:
        return str(subprocess.check_output('git rev-parse --short HEAD'.split()), 'utf-8').strip()
    except:
        return None

def inventreeCommitDate():
    """ Returns the git commit date for the running codebase """

    try:
        d = str(subprocess.check_output('git show -s --format=%ci'.split()), 'utf-8').strip()
        return d.split(' ')[0]
    except:
        return None
<commit_msg>Update version.py<commit_after>""" Version information for InvenTree.
Provides information on the current InvenTree version
"""

import subprocess
import django
import re

import common.models

INVENTREE_SW_VERSION = "0.2.4"

INVENTREE_API_VERSION = 6

"""
Increment thi API version number whenever there is a significant change to the API that any clients need to know about

v6 -> 2021-06-23
    - Part and Company images can now be directly uploaded via the REST API

v5 -> 2021-06-21
    - Adds API interface for manufacturer part parameters

v4 -> 2021-06-01
    - BOM items can now accept "variant stock" to be assigned against them
    - Many slight API tweaks were needed to get this to work properly!

v3 -> 2021-05-22:
    - The updated StockItem "history tracking" now uses a different interface

"""

def inventreeInstanceName():
    """ Returns the InstanceName settings for the current database """
    return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")

def inventreeInstanceTitle():
    """ Returns the InstanceTitle for the current database """
    if common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE_TITLE", False):
        return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")
    else:
        return 'InvenTree'

def inventreeVersion():
    """ Returns the InvenTree version string """
    return INVENTREE_SW_VERSION

def inventreeVersionTuple(version=None):
    """ Return the InvenTree version string as (maj, min, sub) tuple """

    if version is None:
        version = INVENTREE_SW_VERSION

    match = re.match(r"^.*(\d+)\.(\d+)\.(\d+).*$", str(version))

    return [int(g) for g in match.groups()]

def isInvenTreeUpToDate():
    """
    Test if the InvenTree instance is "up to date" with the latest version.

    A background task periodically queries GitHub for latest version,
    and stores it to the database as INVENTREE_LATEST_VERSION
    """

    latest = common.models.InvenTreeSetting.get_setting('INVENTREE_LATEST_VERSION', None)

    # No record for "latest" version - we must assume we are up to date!
    if not latest:
        return True

    # Extract "tuple" version (Python can directly compare version tuples)
    latest_version = inventreeVersionTuple(latest)
    inventree_version = inventreeVersionTuple()

    return inventree_version >= latest_version

def inventreeApiVersion():
    return INVENTREE_API_VERSION

def inventreeDjangoVersion():
    """ Return the version of Django library """
    return django.get_version()

def inventreeCommitHash():
    """ Returns the git commit hash for the running codebase """

    try:
        return str(subprocess.check_output('git rev-parse --short HEAD'.split()), 'utf-8').strip()
    except:
        return None

def inventreeCommitDate():
    """ Returns the git commit date for the running codebase """

    try:
        d = str(subprocess.check_output('git show -s --format=%ci'.split()), 'utf-8').strip()
        return d.split(' ')[0]
    except:
        return None
<|endoftext|>


<commit_before>#04
import sqlite3
def create():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS account(id INTEGER PRIMARY KEY,name TEXT,user TEXT, password TEXT,category TEXT,cdate TEXT)")
    con.commit()
    con.close()
def viewall():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account")
    rows = cur.fetchall()
    con.close()
    return rows

def search(name="",user="",password="",category=""):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account WHERE name=? OR user=? OR password=? OR category=?",(name,user,password,category))
    rows = cur.fetchall()
    con.close()
    return rows
def add(name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("INSERT INTO account VALUES(NULL,?,?,?,?,?)",(name,user,password,category,cdate))
    con.commit()
    con.close()
def update(id,name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("UPDATE account SET name=?,user=?,password=?,category=?,cdate=? WHERE id=?",(name,user,password,category,cdate,id))
    con.commit()
    con.close()
def delete(id):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("DELETE FROM account WHERE id=?",(id,))
    con.commit()
    con.close()
create()
#print(search(category="social"))
=======
import sqlite3
def create():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS account(id INTEGER PRIMARY KEY,name TEXT,user TEXT, password TEXT,category TEXT,cdate TEXT)")
    con.commit()
    con.close()
def viewall():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account")
    rows = cur.fetchall()
    con.close()
    return rows

def search(name="",user="",password="",category=""):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account WHERE name=? OR user=? OR password=? OR category=?",(name,user,password,category))
    rows = cur.fetchall()
    con.close()
    return rows
def add(name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("INSERT INTO account VALUES(NULL,?,?,?,?,?)",(name,user,password,category,cdate))
    con.commit()
    con.close()
def update(id,name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("UPDATE account SET name=?,user=?,password=?,category=?,cdate=? WHERE id=?",(name,user,password,category,cdate,id))
    con.commit()
    con.close()
def delete(id):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("DELETE FROM account WHERE id=?",(id,))
    con.commit()
    con.close()
create()
#print(search(category="social"))
=======
import sqlite3
def create(): #DB생성
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS account(id INTEGER PRIMARY KEY,name TEXT,user TEXT, password TEXT,category TEXT,cdate TEXT)")
    #INTEGER PRIMARY KEY를 계좌번호로
    con.commit()
    con.close()

def viewall(): #DB에 저장된 모든 정보 불러옴
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account")
    rows = cur.fetchall() #모든 줄 출력
    con.close()
    return rows

def search(name="",user="",password="",category=""): #원하는 정보를 찾음
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account WHERE name=? OR user=? OR password=? OR category=?",(name,user,password,category))
    rows = cur.fetchall() #찾아온 정보를 모두 출력
    con.close()
    return rows

def add(name,user,password,category,cdate): #DB에 새로운 정보 입력
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("INSERT INTO account VALUES(NULL,?,?,?,?,?)",(name,user,password,category,cdate))
    con.commit()
    con.close()

def update(id,name,user,password,category,cdate): #있는 정보를 업데이트함
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("UPDATE account SET name=?,user=?,password=?,category=?,cdate=? WHERE id=?",(name,user,password,category,cdate,id))
    con.commit()
    con.close()

def delete(id): #DB에 있는 정보 중 원하는 정보 삭제
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("DELETE FROM account WHERE id=?",(id,))
    con.commit()
    con.close()
create()
#print(search(category="social"))<commit_msg>44번 줄 이후 중복된 부분 삭제<commit_after>#04
import sqlite3
def create():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS account(id INTEGER PRIMARY KEY,name TEXT,user TEXT, password TEXT,category TEXT,cdate TEXT)")
    con.commit()
    con.close()

def viewall():
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account")
    rows = cur.fetchall()
    con.close()
    return rows

def search(name="",user="",password="",category=""):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("SELECT * FROM account WHERE name=? OR user=? OR password=? OR category=?",(name,user,password,category))
    rows = cur.fetchall()
    con.close()
    return rows
def add(name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("INSERT INTO account VALUES(NULL,?,?,?,?,?)",(name,user,password,category,cdate))
    con.commit()
    con.close()
def update(id,name,user,password,category,cdate):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("UPDATE account SET name=?,user=?,password=?,category=?,cdate=? WHERE id=?",(name,user,password,category,cdate,id))
    con.commit()
    con.close()
def delete(id):
    con = sqlite3.connect("aledger.db")
    cur = con.cursor()
    cur.execute("DELETE FROM account WHERE id=?",(id,))
    con.commit()
    con.close()
create()
#print(search(category="social"))<|endoftext|>


<commit_before>import sys
import os
import argparse
import collections
import unidecode
import shutil
import json
import codecs

import compmusic.musicbrainz
import musicbrainzngs as mb
mb.set_useragent("Dunya", "0.1")
mb.set_rate_limit(False)
mb.set_hostname("sitar.s.upf.edu:8090")

def main(collectionid):
    # work -> list recordings
    mapping = collections.defaultdict(list)
    # map from an id to a name
    recordingnames = {}
    worknames = {}
    for i, releaseid in enumerate(compmusic.musicbrainz.get_releases_in_collection(collectionid)):
        print i, releaseid
        try:
            rel = mb.get_release_by_id(releaseid, includes=["recordings"])
        except:
            continue
        rel = rel["release"]

        for medium in rel.get("medium-list", []):
            for track in medium.get("track-list", []):
                recid = track["recording"]["id"]
                recordingnames[recid] = track["recording"]["title"]
                recording = mb.get_recording_by_id(recid, includes=["work-rels"])
                recording = recording["recording"]
                for work in recording.get("work-relation-list", []):
                    workid = work["work"]["id"]
                    worknames[workid] = work["work"]["title"]
                    mapping[workid].append(recid)

    data = []
    for k, v in mapping.items():
        data.append((k, v))
    data = sorted(data, key=lambda x: len(x[1]), reverse=True)
    all_d = {"recordingnames": recordingnames,
            "worknames": worknames,
            "data": data
            }
    json.dump(all_d, open("works_by_recording.json", "w"))

def dump_data():
    all_d = json.load(open("works_by_recording.json"))
    data = all_d["data"]
    data = sorted(data, key=lambda x: len(x[1]), reverse=True)
    worknames = all_d["worknames"]
    recordingnames = all_d["recordingnames"]
    output = codecs.open("works.html", "w","utf8")
    output.write("")
    output.write('<meta charset="utf-8">\n')
    output.write("<title>Works</title>\n")
    output.write("
\n")
    for d in data:
        i = d[0]
        output.write(u'
%s
\n' % (i, worknames[i]))
        output.write("
")
        for e in d[1]:
            output.write(u'
%s
\n' % (e, recordingnames[e]))
        output.write("
")
    output.write("
")

if __name__ == "__main__":
    p = argparse.ArgumentParser()
    p.add_argument("-c", help="collection id")
    args = p.parse_args()
    if not os.path.exists("works_by_recording.json"):
        main(args.c)
    dump_data()
<commit_msg>copy files when making html<commit_after>import sys
import os
import argparse
import collections
import unidecode
import shutil
import json
import codecs

import compmusic.musicbrainz
import musicbrainzngs as mb
mb.set_useragent("Dunya", "0.1")
mb.set_rate_limit(False)
mb.set_hostname("sitar.s.upf.edu:8090")

if os.path.exists("recording_to_file.json"):
    recording_to_file = json.load(open("recording_to_file.json"))
else:
    recording_to_file = {}

TARGET_DIR = "audio"

def copy_recordingid_to_dir(recordingid):
    files = recording_to_file.get(recordingid, [])
    for fname in files:
        name = os.path.basename(fname)
        n, ext = os.path.splitext(name)
        if os.path.exists(os.path.join(TARGET_DIR, n)):
            sourcedir = os.path.dirname(fname)
            rand = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(4))
            ndir = "%s_%s" % (n, rand)
            newname = "%s%s" % (ndir, ext)
            newdest = os.path.join(TARGET_DIR, ndir, newname)
            try:
                os.makedirs(os.path.dirname(newdest))
            except:
                pass
            print name, "exists, copying", target, "to", newname, "instead"
            shutil.copy(fname, newdest)
        else:
            innertarget = os.path.join(TARGET_DIR, n)
            try:
                os.makedirs(innertarget)
            except:
                pass
            shutil.copy(fname, innertarget)

def main(collectionid):
    # work -> list recordings
    mapping = collections.defaultdict(list)
    # map from an id to a name
    recordingnames = {}
    worknames = {}
    for i, releaseid in enumerate(compmusic.musicbrainz.get_releases_in_collection(collectionid)):
        print i, releaseid
        try:
            rel = mb.get_release_by_id(releaseid, includes=["recordings"])
        except:
            continue
        rel = rel["release"]

        for medium in rel.get("medium-list", []):
            for track in medium.get("track-list", []):
                recid = track["recording"]["id"]
                recordingnames[recid] = track["recording"]["title"]
                recording = mb.get_recording_by_id(recid, includes=["work-rels"])
                recording = recording["recording"]
                for work in recording.get("work-relation-list", []):
                    workid = work["work"]["id"]
                    worknames[workid] = work["work"]["title"]
                    mapping[workid].append(recid)

    data = []
    for k, v in mapping.items():
        data.append((k, v))
    data = sorted(data, key=lambda x: len(x[1]), reverse=True)
    all_d = {"recordingnames": recordingnames,
            "worknames": worknames,
            "data": data
            }
    json.dump(all_d, open("works_by_recording.json", "w"))

def dump_data():
    all_d = json.load(open("works_by_recording.json"))
    data = all_d["data"]
    data = sorted(data, key=lambda x: len(x[1]), reverse=True)
    worknames = all_d["worknames"]
    recordingnames = all_d["recordingnames"]
    output = codecs.open("works.html", "w","utf8")
    output.write("")
    output.write('<meta charset="utf-8">\n')
    output.write("<title>Works</title>\n")
    output.write("
\n")
    for d in data:
        i = d[0]
        output.write(u'
%s
\n' % (i, worknames[i]))
        output.write("
")
        for e in d[1]:
            copy_recordingid_to_dir(e)
            output.write(u'
%s
\n' % (e, recordingnames[e]))
        output.write("
")
    output.write("
")

if __name__ == "__main__":
    p = argparse.ArgumentParser()
    p.add_argument("-c", help="collection id")
    args = p.parse_args()
    if not os.path.exists("works_by_recording.json"):
        main(args.c)
    dump_data()
<|endoftext|>


<commit_before><commit_msg>Modernize Python print syntax.<commit_after><|endoftext|>


<commit_before>"""Build the tutorial data files from the IMDB *.list.gz files."""

import csv
import gzip
import os
import re
from datetime import datetime

split_on_tabs = re.compile(b'\t+').split

BAD_GENRES = {b'Adult', b'Documentary', b'Short', b'Horror', b'Reality-TV',
              b'Talk-Show', b'Game-Show', b'Reality-tv'}

def main():
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    if not os.path.isdir('../data'):
        os.makedirs('../data')

    # Load movie titles.

    titles = set()
    uninteresting_titles = set()

    lines = iter(gzip.open('genres.list.gz'))
    line = next(lines)
    while line != b'8: THE GENRES LIST\n':
        line = next(lines)
    assert next(lines) == b'==================\n'
    assert next(lines) == b'\n'

    print('Reading "genres.list.gz" to find interesting movies')

    for line in lines:
        if not_a_real_movie(line):
            continue

        fields = split_on_tabs(line.strip(b'\n'))
        raw_title = fields[0]
        genre = fields[1]

        try:
            raw_title.decode('ascii')
        except UnicodeDecodeError:
            continue

        if genre in BAD_GENRES:
            uninteresting_titles.add(raw_title)
        else:
            titles.add(raw_title)

    interesting_titles = titles - uninteresting_titles
    del titles
    del uninteresting_titles

    print('Found {0} titles'.format(len(interesting_titles)))

    print('Writing "titles.csv"')

    with open('../data/titles.csv', 'w') as f:
        output = csv.writer(f)
        output.writerow(('title', 'year'))
        for raw_title in interesting_titles:
            title_and_year = parse_title(raw_title)
            output.writerow(title_and_year)

    print('Finished writing "titles.csv"')
    print('Reading release dates from "release-dates.list.gz"')

    lines = iter(gzip.open('release-dates.list.gz'))
    line = next(lines)
    while line != b'RELEASE DATES LIST\n':
        line = next(lines)
    assert next(lines) == b'==================\n'

    output = csv.writer(open('../data/release_dates.csv', 'w'))
    output.writerow(('title', 'year', 'country', 'date'))

    for line in lines:
        if not_a_real_movie(line):
            continue

        if line.startswith(b'----'):
            continue

        fields = split_on_tabs(line.strip(b'\n'))
        if len(fields) > 2:     # ignore "DVD premier" lines and so forth
            continue

        raw_title = fields[0]
        if raw_title not in interesting_titles:
            continue

        title, year = parse_title(raw_title)
        if title is None:
            continue

        country, datestr = fields[1].decode('ascii').split(':')
        try:
            date = datetime.strptime(datestr, '%d %B %Y').date()
        except ValueError:
            continue  # incomplete dates like "April 2014"
        output.writerow((title, year, country, date))

    print('Finished writing "release_dates.csv"')

    output = csv.writer(open('../data/cast.csv', 'w'))
    output.writerow(('title', 'year', 'name', 'type', 'character', 'n'))

    for role_type, filename in (
            ('actor', 'actors.list.gz'),
            ('actress', 'actresses.list.gz'),
            ):
        print('Reading {0!r}'.format(filename))
        lines = iter(gzip.open(filename))

        line = next(lines)
        while (b'Name' not in line) or (b'Titles' not in line):
            line = next(lines)

        assert b'----' in next(lines)

        for line in lines:
            if line.startswith(b'----------------------'):
                break

            line = line.rstrip()
            if not line:
                continue

            fields = split_on_tabs(line.strip(b'\n'))
            if fields[0]:
                name = decode_ascii(fields[0])
                name = swap_names(name)

            if len(fields) < 2:
                raise ValueError('broken line: {!r}'.format(line))

            if not_a_real_movie(fields[1]):
                continue

            fields = fields[1].split(b'  ')
            raw_title = fields[0]
            if raw_title not in interesting_titles:
                continue

            if len(fields) < 2:
                continue

            if fields[1].startswith(b'('):  # uncredited, archive footage, etc
                del fields[1]
                if len(fields) < 2:
                    continue

            if not fields[1].startswith(b'['):
                continue

            character = decode_ascii(fields[1].strip(b'[]'))

            if len(fields) > 2 and fields[2].startswith(b'<'):
                n = int(fields[2].strip(b'<>'))
            else:
                n = ''

            title, year = parse_title(raw_title)
            if title is None:
                continue

            if character == 'N/A':
                clist = ['(N/A)']
            else:
                clist = character.split('/')

            for character in clist:
                if not character:
                    continue
                output.writerow((title, year, name, role_type, character, n))

    print('Finished writing "cast.csv"')

def not_a_real_movie(line):
    return (
        line.startswith(b'"')       # TV show
        or b'{' in line             # TV episode
        or b' (????' in line        # Unknown year
        or b' (TV)' in line         # TV Movie
        or b' (V)' in line          # Video
        or b' (VG)' in line         # Video game
        or b' (segment ' in line    # Anthology film
        )

match_title = re.compile(r'^(.*) \((\d+)(/[IVXL]+)?\)$').match

def parse_title(raw_title):
    try:
        title = raw_title.decode('ascii')
    except UnicodeDecodeError:
        return None, None

    m = match_title(title)
    title = m.group(1)
    year = int(m.group(2))
    numeral = m.group(3)

    if numeral is not None:
        numeral = numeral.strip('/')
        if numeral != 'I':
            title = '{0} ({1})'.format(title, numeral)

    return title, year

def swap_names(name):
    if name.endswith(' (I)'):
        name = name[:-4]
    if ',' in name:
        last, first = name.split(',', 1)
        name = first.strip() + ' ' + last.strip()
    return name

def decode_ascii(s):
    return s.decode('latin-1') #ascii', 'replace').replace(u'\ufffd', u'?')

if __name__ == '__main__':
    main()
<commit_msg>Specify UTF-8 encoding when writing cast.csv (#53)<commit_after>"""Build the tutorial data files from the IMDB *.list.gz files."""

import csv
import gzip
import os
import re
import sys
from datetime import datetime

split_on_tabs = re.compile(b'\t+').split

BAD_GENRES = {b'Adult', b'Documentary', b'Short', b'Horror', b'Reality-TV',
              b'Talk-Show', b'Game-Show', b'Reality-tv'}

def main():
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    if not os.path.isdir('../data'):
        os.makedirs('../data')

    # Load movie titles.

    titles = set()
    uninteresting_titles = set()

    lines = iter(gzip.open('genres.list.gz'))
    line = next(lines)
    while line != b'8: THE GENRES LIST\n':
        line = next(lines)
    assert next(lines) == b'==================\n'
    assert next(lines) == b'\n'

    print('Reading "genres.list.gz" to find interesting movies')

    for line in lines:
        if not_a_real_movie(line):
            continue

        fields = split_on_tabs(line.strip(b'\n'))
        raw_title = fields[0]
        genre = fields[1]

        try:
            raw_title.decode('ascii')
        except UnicodeDecodeError:
            continue

        if genre in BAD_GENRES:
            uninteresting_titles.add(raw_title)
        else:
            titles.add(raw_title)

    interesting_titles = titles - uninteresting_titles
    del titles
    del uninteresting_titles

    print('Found {0} titles'.format(len(interesting_titles)))

    print('Writing "titles.csv"')

    with open('../data/titles.csv', 'w') as f:
        output = csv.writer(f)
        output.writerow(('title', 'year'))
        for raw_title in interesting_titles:
            title_and_year = parse_title(raw_title)
            output.writerow(title_and_year)

    print('Finished writing "titles.csv"')
    print('Reading release dates from "release-dates.list.gz"')

    lines = iter(gzip.open('release-dates.list.gz'))
    line = next(lines)
    while line != b'RELEASE DATES LIST\n':
        line = next(lines)
    assert next(lines) == b'==================\n'

    output = csv.writer(open('../data/release_dates.csv', 'w'))
    output.writerow(('title', 'year', 'country', 'date'))

    for line in lines:
        if not_a_real_movie(line):
            continue

        if line.startswith(b'----'):
            continue

        fields = split_on_tabs(line.strip(b'\n'))
        if len(fields) > 2:     # ignore "DVD premier" lines and so forth
            continue

        raw_title = fields[0]
        if raw_title not in interesting_titles:
            continue

        title, year = parse_title(raw_title)
        if title is None:
            continue

        country, datestr = fields[1].decode('ascii').split(':')
        try:
            date = datetime.strptime(datestr, '%d %B %Y').date()
        except ValueError:
            continue  # incomplete dates like "April 2014"
        output.writerow((title, year, country, date))

    print('Finished writing "release_dates.csv"')

    if sys.version_info < (3, 0):
        output = csv.writer(open('../data/cast.csv', 'w'))
    else:
        output = csv.writer(open('../data/cast.csv', 'w', encoding='utf-8'))
    output.writerow(('title', 'year', 'name', 'type', 'character', 'n'))

    for role_type, filename in (
            ('actor', 'actors.list.gz'),
            ('actress', 'actresses.list.gz'),
            ):
        print('Reading {0!r}'.format(filename))
        lines = iter(gzip.open(filename))

        line = next(lines)
        while (b'Name' not in line) or (b'Titles' not in line):
            line = next(lines)

        assert b'----' in next(lines)

        for line in lines:
            if line.startswith(b'----------------------'):
                break

            line = line.rstrip()
            if not line:
                continue

            fields = split_on_tabs(line.strip(b'\n'))
            if fields[0]:
                name = decode_ascii(fields[0])
                name = swap_names(name)

            if len(fields) < 2:
                raise ValueError('broken line: {!r}'.format(line))

            if not_a_real_movie(fields[1]):
                continue

            fields = fields[1].split(b'  ')
            raw_title = fields[0]
            if raw_title not in interesting_titles:
                continue

            if len(fields) < 2:
                continue

            if fields[1].startswith(b'('):  # uncredited, archive footage, etc
                del fields[1]
                if len(fields) < 2:
                    continue

            if not fields[1].startswith(b'['):
                continue

            character = decode_ascii(fields[1].strip(b'[]'))

            if len(fields) > 2 and fields[2].startswith(b'<'):
                n = int(fields[2].strip(b'<>'))
            else:
                n = ''

            title, year = parse_title(raw_title)
            if title is None:
                continue

            if character == 'N/A':
                clist = ['(N/A)']
            else:
                clist = character.split('/')

            for character in clist:
                if not character:
                    continue
                output.writerow((title, year, name, role_type, character, n))

    print('Finished writing "cast.csv"')

def not_a_real_movie(line):
    return (
        line.startswith(b'"')       # TV show
        or b'{' in line             # TV episode
        or b' (????' in line        # Unknown year
        or b' (TV)' in line         # TV Movie
        or b' (V)' in line          # Video
        or b' (VG)' in line         # Video game
        or b' (segment ' in line    # Anthology film
        )

match_title = re.compile(r'^(.*) \((\d+)(/[IVXL]+)?\)$').match

def parse_title(raw_title):
    try:
        title = raw_title.decode('ascii')
    except UnicodeDecodeError:
        return None, None

    m = match_title(title)
    title = m.group(1)
    year = int(m.group(2))
    numeral = m.group(3)

    if numeral is not None:
        numeral = numeral.strip('/')
        if numeral != 'I':
            title = '{0} ({1})'.format(title, numeral)

    return title, year

def swap_names(name):
    if name.endswith(' (I)'):
        name = name[:-4]
    if ',' in name:
        last, first = name.split(',', 1)
        name = first.strip() + ' ' + last.strip()
    return name

def decode_ascii(s):
    return s.decode('latin-1') #ascii', 'replace').replace(u'\ufffd', u'?')

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>from ._crontab import CronTabCallback, crontab

version = "0.3"
<commit_msg>Bump master version number to 0.4.dev1<commit_after>from ._crontab import CronTabCallback, crontab

version = "0.4.dev1"
<|endoftext|>


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

# Copyright 2015 2016 Juca Crispim <juca@poraodojuca.net>

# This file is part of toxicbuild.

# toxicbuild is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# toxicbuild is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with toxicbuild. If not, see <http://www.gnu.org/licenses/>.

import asyncio
import os
from toxicbuild.slave.exceptions import PluginNotFound
from toxicbuild.slave.build import BuildStep

class Plugin:

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

    # Your plugin must have an unique name
    name = 'BasePlugin'

    @classmethod
    def get(cls, name):
        """ Returns a Plugin subclass based on its name."""

        for plugin in cls.__subclasses__():
            if plugin.name == name:
                return plugin
        raise PluginNotFound('Plugin {} does not exist.'.format(name))

    def get_steps_before(self):
        """Returns a list of steps to be executed before the steps provided
        by the user."""

        return []

    def get_steps_after(self):
        """Returns a list of steps to be executed after the steps provided
        by the user."""

        return []

    def get_env_vars(self):
        """ Returns a dictionary containing values for environment
        variables."""

        return {}

class PythonCreateVenvStep(BuildStep):

    """Step that checks if the venv already exists before
    executing the command."""

    def __init__(self, venv_dir, pyversion):
        self.venv_dir = venv_dir
        self.pyversion = pyversion
        name = 'Create virtualenv'
        command = 'virtualenv {} -p {}'.format(self.venv_dir,
                                               self.pyversion)
        super().__init__(name, command, stop_on_fail=True)

    @asyncio.coroutine
    def execute(self, cwd, **envvars):
        pyexec = os.path.join(self.venv_dir, os.path.join('bin', 'python'))
        if os.path.exists(os.path.join(cwd, pyexec)):
            step_info = {'status': 'success',
                         'output': 'venv exists. Skipping...'}
        else:
            step_info = yield from super().execute(cwd, **envvars)

        return step_info

class PythonVenvPlugin(Plugin):
    name = 'python-venv'

    def __init__(self, pyversion, requirements_file='requirements.txt',
                 remove_env=False):
        self.pyversion = pyversion
        self.requirements_file = requirements_file
        self.remove_env = remove_env
        self.venv_dir = 'venv-{}'.format(self.pyversion.replace(os.sep, ''))

    def get_steps_before(self):
        create_env = PythonCreateVenvStep(self.venv_dir, self.pyversion)

        install_deps = BuildStep('install dependencies using pip',
                                 'pip install -r {}'.format(
                                     self.requirements_file),
                                 stop_on_fail=True)

        return [create_env, install_deps]

    def get_steps_after(self):
        steps = []
        if self.remove_env:
            steps.append(BuildStep('remove venv',
                                   'rm -rf {}'.format(self.venv_dir)))
        return steps

    def get_env_vars(self):
        return {'PATH': '{}/bin:PATH'.format(self.venv_dir)}

class AptitudeInstallStep(BuildStep):

    def __init__(self, packages):
        packages = ' '.join(packages)
        cmd = ' '.join(['aptitude install -y', packages])
        name = 'Installing packages with aptitude'
        super().__init__(name, cmd, stop_on_fail=True)

    @asyncio.coroutine
    def execute(self, cwd, **envvars):
        # here is a hack to avoid break the build when another process
        # is using apt.
        step_info = yield from super().execute(cwd, **envvars)
        status = step_info['status']
        output = step_info['output']
        busy_apt = (status == 'fail' and
                    'is another process using it?' in output)

        while busy_apt:
            yield from asyncio.sleep(1)
            step_info = yield from super().execute(cwd, **envvars)
            status = step_info['status']
            output = step_info['output']
            busy_apt = (status == 'fail' and
                        'another process using it?' in output)

        return step_info

class AptitudeInstallPlugin(Plugin):

    """Installs packages using aptitude."""

    name = 'aptitude-install'

    def __init__(self, packages):
        """Initializes the plugin.
        :param packages: A list of packages names to be installed."""

        self.packages = packages

    def get_steps_before(self):
        step = AptitudeInstallStep(self.packages)
        return [step]
<commit_msg>slave.plugin: adding timeout to aptitude install<commit_after># -*- coding: utf-8 -*-

# Copyright 2015 2016 Juca Crispim <juca@poraodojuca.net>

# This file is part of toxicbuild.

# toxicbuild is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# toxicbuild is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with toxicbuild. If not, see <http://www.gnu.org/licenses/>.

import asyncio
import os
from toxicbuild.slave.exceptions import PluginNotFound
from toxicbuild.slave.build import BuildStep

class Plugin:

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

    # Your plugin must have an unique name
    name = 'BasePlugin'

    @classmethod
    def get(cls, name):
        """ Returns a Plugin subclass based on its name."""

        for plugin in cls.__subclasses__():
            if plugin.name == name:
                return plugin
        raise PluginNotFound('Plugin {} does not exist.'.format(name))

    def get_steps_before(self):
        """Returns a list of steps to be executed before the steps provided
        by the user."""

        return []

    def get_steps_after(self):
        """Returns a list of steps to be executed after the steps provided
        by the user."""

        return []

    def get_env_vars(self):
        """ Returns a dictionary containing values for environment
        variables."""

        return {}

class PythonCreateVenvStep(BuildStep):

    """Step that checks if the venv already exists before
    executing the command."""

    def __init__(self, venv_dir, pyversion):
        self.venv_dir = venv_dir
        self.pyversion = pyversion
        name = 'Create virtualenv'
        command = 'virtualenv {} -p {}'.format(self.venv_dir,
                                               self.pyversion)
        super().__init__(name, command, stop_on_fail=True)

    @asyncio.coroutine
    def execute(self, cwd, **envvars):
        pyexec = os.path.join(self.venv_dir, os.path.join('bin', 'python'))
        if os.path.exists(os.path.join(cwd, pyexec)):
            step_info = {'status': 'success',
                         'output': 'venv exists. Skipping...'}
        else:
            step_info = yield from super().execute(cwd, **envvars)

        return step_info

class PythonVenvPlugin(Plugin):
    name = 'python-venv'

    def __init__(self, pyversion, requirements_file='requirements.txt',
                 remove_env=False):
        self.pyversion = pyversion
        self.requirements_file = requirements_file
        self.remove_env = remove_env
        self.venv_dir = 'venv-{}'.format(self.pyversion.replace(os.sep, ''))

    def get_steps_before(self):
        create_env = PythonCreateVenvStep(self.venv_dir, self.pyversion)

        install_deps = BuildStep('install dependencies using pip',
                                 'pip install -r {}'.format(
                                     self.requirements_file),
                                 stop_on_fail=True)

        return [create_env, install_deps]

    def get_steps_after(self):
        steps = []
        if self.remove_env:
            steps.append(BuildStep('remove venv',
                                   'rm -rf {}'.format(self.venv_dir)))
        return steps

    def get_env_vars(self):
        return {'PATH': '{}/bin:PATH'.format(self.venv_dir)}

class AptitudeInstallStep(BuildStep):

    def __init__(self, packages, timeout=600):
        packages = ' '.join(packages)
        cmd = ' '.join(['aptitude install -y', packages])
        name = 'Installing packages with aptitude'
        super().__init__(name, cmd, stop_on_fail=True, timeout=timeout)

    @asyncio.coroutine
    def execute(self, cwd, **envvars):
        # here is a hack to avoid break the build when another process
        # is using apt.
        step_info = yield from super().execute(cwd, **envvars)
        status = step_info['status']
        output = step_info['output']
        busy_apt = (status == 'fail' and
                    'is another process using it?' in output)

        while busy_apt:
            yield from asyncio.sleep(1)
            step_info = yield from super().execute(cwd, **envvars)
            status = step_info['status']
            output = step_info['output']
            busy_apt = (status == 'fail' and
                        'another process using it?' in output)

        return step_info

class AptitudeInstallPlugin(Plugin):

    """Installs packages using aptitude."""

    name = 'aptitude-install'

    def __init__(self, packages, timeout=600):
        """Initializes the plugin.
        :param packages: A list of packages names to be installed."""

        self.packages = packages

    def get_steps_before(self):
        step = AptitudeInstallStep(self.packages)
        return [step]
<|endoftext|>