Exemplo n.º 1
0
class GoogleTrack(GoogleTrackBase):
    """A track from Google."""
    duration = attrib(default=Factory(timedelta))
    genre = attrib(default=Factory(lambda: None))
    album_id = attrib(default=Factory(lambda: None))
    artist_ids = attrib(default=Factory(list))

    def get_stream(self):
        """Check this track has been downloaded first."""
        assert self.id is not None
        name = '%s.mp3' % self.id
        state = backend.get_download_state(name)
        if state is DownloadStates.downloaded:
            return FileStream(file=backend.get_full_path(name))
        else:
            url = api.get_stream_url(self.id)
            if state is DownloadStates.none:
                add_job('Download track %r' % self,
                        lambda: backend.download_file(url, name))
            return URLStream(url.encode())

    @classmethod
    def from_dict(cls, data):
        """Create a Track instance from a track dictionary from Google."""
        return cls(data.get('artist', 'Unknown Artist'),
                   data.get('album', 'Unknown Album'),
                   data.get('trackNumber', 0),
                   data.get('title', 'Unknown Title'),
                   duration=timedelta(
                       milliseconds=int(data.get('durationMillis', '0'))),
                   genre=data.get('genre', 'Unknown Genre'),
                   id=get_id(data),
                   album_id=data.get('albumId', None),
                   artist_ids=data.get('artistId', []))
Exemplo n.º 2
0
class AudioBlockFormatObjects(AudioBlockFormat):
    """ADM audioBlockFormat with typeDefinition == "Objects"

    Attributes:
        position (Optional[ObjectPosition])
        cartesian (bool)
        width (float)
        height (float)
        depth (float)
        gain (float)
        diffuse (float)
        channelLock (Optional[ChannelLock])
        objectDivergence (Optional[ObjectDivergence])
        jumpPosition (JumpPosition)
        screenRef (bool)
        importance (int)
        zoneExclusion (list[Union[CartesianZone, PolarZone]])
    """

    position = attrib(default=None, validator=instance_of(ObjectPosition), converter=convert_object_position)
    cartesian = attrib(converter=bool, default=False)
    width = attrib(converter=float, default=0.)
    height = attrib(converter=float, default=0.)
    depth = attrib(converter=float, default=0.)
    gain = attrib(converter=float, default=1.)
    diffuse = attrib(converter=float, default=0.)
    channelLock = attrib(default=None, validator=optional(instance_of(ChannelLock)))
    objectDivergence = attrib(default=None, validator=optional(instance_of(ObjectDivergence)))
    jumpPosition = attrib(default=Factory(JumpPosition))
    screenRef = attrib(converter=bool, default=False)
    importance = attrib(default=10, validator=instance_of(int))
    zoneExclusion = attrib(default=Factory(list), validator=list_of((CartesianZone, PolarZone)))
Exemplo n.º 3
0
class Renderer:
    """Used to render PLP documents."""

    start = attrib(default=Factory(lambda: '<?python'))
    end = attrib(default=Factory(lambda: '?>'))
    filename = attrib(default=Factory(lambda: '<PLP Renderer>'))

    def render(self, string, **kwargs):
        """Render a string, replacing all code inside of a <?python ?> block
        with anything printed by that block. All kwargs are passed to eval."""
        s = ''
        while string.count(self.start):
            start_pos = string.find(self.start)
            s += string[:start_pos]
            code_start_pos = start_pos + len(self.start)
            code_end_pos = string.find(self.end, code_start_pos)
            if code_end_pos == -1:
                lines = string.count('\n', 0, start_pos)
                cols = string.split('\n')[lines].find(self.start) + 1
                lines += 1
                raise UnclosedTag(
                    f'The tag opened on line {lines} column {cols} is '
                    'unclosed.')
            code = string[code_start_pos:code_end_pos]
            c = compile(code, self.filename, 'exec')
            f = StringIO()
            with redirect_stdout(f):
                eval(c, kwargs)
            f.seek(0)
            s += f.read()[:-1]
            string = string[code_end_pos + len(self.end):]
        return s + string
Exemplo n.º 4
0
class FileContextManager():
    include_paths: list = Factory(list)
    files: Dict = Factory(dict)

    def search_file(self, filename):
        for inc in self.include_paths:
            test = os.path.expanduser(os.path.join(inc, filename))
            if os.path.isfile(test):
                return test
        return None

    def search_expr(self, glob_expr):
        for inc in self.include_paths:
            for result in glob.glob(os.path.join(inc, glob_expr),
                                    recursive=True):
                yield result

    # TODO: rename to get_data()
    def get_text(self, filename, mode='rt'):
        if filename not in self.files:
            full_filename = self.search_file(filename)
            if not full_filename:
                raise FileContextException(
                    f'Cannot find "{filename}" on any configured search path.')
            with open(full_filename, mode) as f:
                self.files[filename] = f.read()
        return self.files[filename]
Exemplo n.º 5
0
class AudioProgramme(ADMElement):
    """ADM audioProgramme

    Attributes:
        audioProgrammeName (str)
        audioProgrammeLanguage (Optional[str])
        start (Optional[fractions.Fraction])
        end (Optional[fractions.Fraction])
        maxDuckingDepth (Optional[float])
        audioContents (list[AudioContent]): audioContent elements referenced
            via audioContentIDRef
        referenceScreen (Optional[Union[CartesianScreen, PolarScreen]])
        loudnessMetadata (list[LoudnessMetadata])
    """

    audioProgrammeName = attrib(default=None, validator=instance_of(string_types))
    audioProgrammeLanguage = attrib(default=None)
    start = attrib(default=None)
    end = attrib(default=None)
    maxDuckingDepth = attrib(default=None)
    audioContents = attrib(default=Factory(list), repr=False)

    audioContentIDRef = attrib(default=Factory(list))

    referenceScreen = attrib(validator=optional(instance_of((CartesianScreen, PolarScreen))),
                             default=default_screen)
    loudnessMetadata = attrib(default=Factory(list), validator=list_of(LoudnessMetadata))

    def lazy_lookup_references(self, adm):
        if self.audioContentIDRef is not None:
            self.audioContents = _lookup_elements(adm, self.audioContentIDRef)
            self.audioContentIDRef = None
Exemplo n.º 6
0
class Task:
    """A task. Uses twisted.internet.task.LoopingCall."""

    game = attrib()
    func = attrib()
    id = attrib(default=Factory(NoneType), init=False)
    loop = attrib(default=Factory(NoneType), init=False, repr=False)
    deferred = attrib(default=Factory(NoneType), init=False, repr=False)
    logger = attrib(default=Factory(NoneType), init=False, repr=False)

    def __attrs_post_init__(self):
        self.id = self.game.new_id()
        self.logger = getLogger('%s (#%s)' % (self.func.__name__, self.id))
        args = []
        ctx = dict(game=self.game, task=self, id=self.id)
        for parameter in signature(self.func).parameters.values():
            try:
                args.append(ctx[parameter.name])
            except KeyError:
                if parameter.default is parameter.empty:
                    raise InvalidArgumentError(parameter.name, ctx)
        self.func = partial(self.func, *args)
        self.loop = LoopingCall(self.func)

    def start(self, *args, **kwargs):
        """Call self.loop.start with all arguments, and store the resulting
        Deferred in self.deferred."""
        self.deferred = self.loop.start(*args, **kwargs)
        self.deferred.addErrback(self.on_error)

    def on_error(self, e):
        self.logger.error('An error occurred:\n' + e.getTraceback())
Exemplo n.º 7
0
class Integration(object):
    """Integration model."""

    parameters = attrib(type=str)
    display_name = attrib(type=str)
    required_fields = attrib(type=list)
    polling_enabled = attrib(type=bool)
    integration_type = attrib(type=str)
    max_send_retries = attrib(type=int)
    supported_event_types = attrib(type=list)
    test_connection_enabled = attrib(type=bool)

    module = attrib(default=None)
    description = attrib(type=str, default=None)
    polling_duration = attrib(type=timedelta, default=0)

    # TODO: Fix schema differences between custom service and integration config.json
    name = attrib(type=str,
                  init=False,
                  default=Factory(
                      lambda self: self.display_name.lower().replace(" ", "_"),
                      takes_self=True))
    label = attrib(type=str,
                   init=False,
                   default=Factory(lambda self: self.description,
                                   takes_self=True))
Exemplo n.º 8
0
class Field:
    """A form field."""

    name = attrib()
    value = attrib()
    type = attrib(default=Factory(lambda: str))
    title = attrib(default=Factory(lambda: None))
    hidden = attrib(default=Factory(bool))

    def __attrs_post_init__(self):
        if self.title is None:
            self.title = self.name.replace(
                '_', ' '
            ).title()

    def dump(self):
        """Return this object as a dict."""
        t = self.type
        assert not isinstance(t, dict), 'Dictionary: %r.' % t
        if isclass(t):
            t = t.__name__
        else:
            if isinstance(t, list):
                res = []
                for item in t:
                    if not isinstance(item, list) or len(item) != 2:
                        if isinstance(item, list):
                            item = item[0]
                        item = [item, item]
                    res.append(item)
                t = res
        return {
            'type': self.__class__.__name__,
            'values': [self.name, self.value, t, self.title, self.hidden]
        }
Exemplo n.º 9
0
class PublicParams(object):
    ec_group = attrib(default=Factory(EcGroup))
    hash_func = attrib(default=Factory(lambda: sha256))
    enc_cipher = attrib(default=Factory(lambda: Cipher("aes-128-gcm")))
    enc_key_size = attrib(default=16)
    lookup_key_size = attrib(default=8)
    nonce_size = attrib(default=16)
Exemplo n.º 10
0
class Engine:
    drawables: List[Sprite] = Factory(list)
    keyPressHandlers: Dict[int, Callable] = Factory(dict)

    def start(self):
        screen = pygame.display.set_mode((640 * 2, 480 * 2),
                                         pygame.locals.SCALED,
                                         vsync=1)

        def handleEvents():
            for event in pygame.event.get():
                if event.type == pygame.locals.KEYUP:
                    handler = self.keyPressHandlers.get(event.key)
                    if handler:
                        handler()

        def drawScene():
            screen.fill((0, 0, 0))
            for drawable in self.drawables:
                drawable.draw(screen)
            return deferToThread(pygame.display.flip)

        LoopingCall(drawScene).start(1 / 62.0)
        LoopingCall(handleEvents).start(1 / 120.0)

    def handleKey(self, key) -> Callable:
        def decorator(decorated):
            self.keyPressHandlers[key] = decorated
            return decorated

        return decorator
Exemplo n.º 11
0
class dialog(object):
    text = attrib()
    type = attrib(default=Factory(int))
    popup_sound = attrib(default=Factory(str))
    SAPI = attrib(default=Factory(bool))

    def __attrs_post_init__(self):
        if self.type:
            self.display(self.type)
        else:
            self.display()

    def display(self, type=1):
        if self.popup_sound != "":
            handle = sound.sound()
            handle.load(self.popup_sound)
            handle.play()
        if type == 1:
            speak(self.text + " To repeat, press R. To dismiss, press enter.",
                  self.SAPI)
        elif type == 2:
            speak(self.text)
        while 1:
            for evt in pygame.event.get():
                if evt.type == pygame.KEYDOWN:
                    if type == 1:
                        if evt.key == pygame.K_r:
                            speak(self.text, self.SAPI)
                    elif type == 2:
                        if evt.key == pygame.K_LEFT or evt.key == pygame.K_RIGHT or evt.key == pygame.K_DOWN or evt.key == pygame.K_UP:
                            speak(self.text)
                        elif evt.key == pygame.K_RETURN or evt.key == pygame.K_SPACE:
                            return 1
                    if evt.key == pygame.K_RETURN:
                        return 1
Exemplo n.º 12
0
class Metronome:
    pulse_delta: float = 0.02  # 125 BPM (0.02 / 60 / 24 pulses per quarter note)
    position: int = 0  # pulses since START
    countdowns: List[Countdown] = Factory(list)
    countdowns_lock: asyncio.Lock = Factory(asyncio.Lock)

    async def wait(self, pulses: int) -> None:
        if pulses == 0:
            return

        countdown = Countdown(pulses)
        async with self.countdowns_lock:
            self.countdowns.append(countdown)
        await countdown

    async def reset(self) -> None:
        self.position = 0
        async with self.countdowns_lock:
            for countdown in self.countdowns:
                if not countdown.done():  # could have been cancelled by CTRL-C
                    countdown.cancel()
            self.countdowns = []

    async def tick(self) -> None:
        self.position += 1
        done_indexes: List[int] = []
        async with self.countdowns_lock:
            for index, countdown in enumerate(self.countdowns):
                countdown.tick()
                if countdown.done():
                    done_indexes.append(index)
            for index in reversed(done_indexes):
                del self.countdowns[index]
Exemplo n.º 13
0
class AudioChannelFormat(ADMElement):
    """ADM audioChannelFormat

    Attributes:
        audioChannelFormatName (str)
        type (TypeDefinition): ``typeDefintion`` and/or ``typeLabel``
        audioBlockFormats (list[AudioBlockFormat])
        frequency (Frequency)
    """

    audioChannelFormatName = attrib(default=None, validator=instance_of(string_types))
    type = attrib(default=None, validator=instance_of(TypeDefinition))
    audioBlockFormats = attrib(default=Factory(list))
    frequency = attrib(default=Factory(Frequency), validator=instance_of(Frequency))

    def lazy_lookup_references(self, adm):
        for block in self.audioBlockFormats:
            block.lazy_lookup_references(adm)

    @audioBlockFormats.validator
    def _validate_audioBlockFormats(self, attr, value):
        from . import block_formats  # can't import at top level without making a loop
        block_type = block_formats.by_type_definition[self.type]
        list_of(block_type)(self, attr, value)

    def validate(self):
        super(AudioChannelFormat, self).validate()
        for block in self.audioBlockFormats:
            block.validate()
Exemplo n.º 14
0
class ModuleContent(object):
    dependencies = attr(default=Factory(set))
    post = attr(default=Factory(list))

    def __iter__(self):
        yield self.dependencies
        yield self.post
Exemplo n.º 15
0
class PlaylistAction(object):
    """A playlist action to be performed once all playlists have been
    localised."""
    # The message for the resulting dialog:
    message = attrib()
    # The title for the resulting dialog:
    title = attrib()
    # The callback to be called:
    callback = attrib()
    # The arguments to call callback with:
    args = attrib(default=Factory(list))
    # The keyword arguments to call callback with:
    kwargs = attrib(default=Factory(dict))

    def __attrs_post_init__(self):
        self.playlists = None

    def complete(self):
        """Call self.callback."""
        playlists = session.query(Playlist).all()
        dlg = wx.SingleChoiceDialog(application.frame, self.message,
                                    self.title, [x.name for x in playlists])
        if dlg.ShowModal() == wx.ID_OK:
            return self.callback(playlists[dlg.GetSelection()], *self.args,
                                 **self.kwargs)
        dlg.Destroy()
Exemplo n.º 16
0
class TestResult(ExecutableItem):
    file_pattern = TEST_CASE_PATTERN

    uuid = attrib(default=None)
    historyId = attrib(default=None)
    fullName = attrib(default=None)
    labels = attrib(default=Factory(list))
    links = attrib(default=Factory(list))
Exemplo n.º 17
0
class Channel(object):
    """Representation of a channel, with a name, real and nominal positions,
    allowed azimuth and elevation ranges, and an lfe flag.

    Attributes:
        name (str): Channel name.
        polar_position (PolarPosition, or arguments for PolarPosition):
            real speaker location
        polar_nominal_position (PolarPosition, or arguments for PolarPosition):
            nominal speaker location, defaults to polar_position
        az_range (2-tuple of floats):
            azimuth range in degrees; allowed range is interpreted as
            starting at az_range[0], moving anticlockwise to az_range[1];
            defaults to the azimuth of polar_nominal_position.
        el_range (2-tuple of floats):
            elevation range in degrees; allowed range is interpreted as
            starting at el_range[0], moving up to el_range[1]; defaults to
            the elevation of polar_nominal_position.
        is_lfe (bool): is this an LFE channel?
    """

    name = attrib(converter=str)
    polar_position = attrib(converter=to_polar_position)
    polar_nominal_position = attrib(converter=to_polar_position,
                                    default=Factory(lambda self: self.polar_position,
                                                    takes_self=True))
    az_range = attrib(default=Factory(lambda self: (self.polar_nominal_position.azimuth,
                                                    self.polar_nominal_position.azimuth),
                                      takes_self=True))
    el_range = attrib(default=Factory(lambda self: (self.polar_nominal_position.elevation,
                                                    self.polar_nominal_position.elevation),
                                      takes_self=True))
    is_lfe = attrib(default=False, converter=bool)

    @property
    def position(self):
        return self.polar_position.as_cartesian_array()

    @property
    def norm_position(self):
        return self.polar_position.norm_position

    @property
    def nominal_position(self):
        return self.polar_nominal_position.as_cartesian_array()

    def check_position(self, callback=_print_warning):
        """Call callback with an error message if the position is outside the
        azimuth and elevation ranges.
        """
        if not inside_angle_range(self.polar_position.azimuth, *self.az_range):
            callback("{name}: azimuth {azimuth} out of range {az_range}.".format(name=self.name,
                                                                                 azimuth=self.polar_position.azimuth,
                                                                                 az_range=self.az_range))
        if not self.el_range[0] <= self.polar_position.elevation <= self.el_range[1]:
            callback("{name}: elevation {elevation} out of range {el_range}.".format(name=self.name,
                                                                                     elevation=self.polar_position.elevation,
                                                                                     el_range=self.el_range))
Exemplo n.º 18
0
class Document:
    name: str
    age: Optional[int] = Factory(lambda: None)
    archived: Optional[bool] = Factory(lambda: False)
    child_field: List[ChildField] = Factory(list)
    id: Optional[str] = Factory(lambda: str(ObjectId()))

    def child_field_index(self, id: str):
        child_field_ids = [sub.id for sub in self.child_field]
        try:
            return child_field_ids.index(id)
        except ValueError:
            return None

    def find_child_field(self, id: str):
        index = self.child_field_index(id)
        if index is None:
            return None
        return self.child_field[index]

    def set_archived(self, value: bool) -> None:
        self.archived = value

    def add_child_field(self, child_field: ChildField):
        self.child_field.append(child_field)

    def remove_child_field(self, id: str) -> None:
        index = self.child_field_index(id)

        if index is None:
            raise KeyError("Could not find child field with id %s" % id)

        del self.child_field[index]

    def update_child_field(self, child_field: ChildField):
        index = self.child_field_index(child_field.id)

        if index is None:
            raise KeyError("Child field with the given index does not exist")

        self.child_field[index] = child_field

    def find_child_field_for_date(self,
                                  sub_date: Date) -> Optional[ChildField]:
        for sub in self.child_field:
            if sub.date == sub_date:
                return sub

    def to_bson(self):
        result = {
            "_id": ObjectId(self.id),
            "name": self.name,
            "age": self.age,
            "child_field": [s.to_bson() for s in self.child_field],
            "archived": self.archived
        }

        return result
Exemplo n.º 19
0
class AugmentedChart(PureChart):
    """A timed chart with attached metadata and timing data."""
    step_artist: Optional[str] = None
    diff_name: str = 'Beginner'
    diff_value: int = 1
    note_field: TimedNotefield = Factory(TimedNotefield)
    bpm_segments: List[MeasureBPMPair] = Factory(list)
    stop_segments: List[MeasureMeasurePair] = Factory(list)
    offset: Time = 0
Exemplo n.º 20
0
class SourceFileSet(object):

    name: str = None
    language: str = None
    compiler: str = None
    compilerOptions: str = None
    preprocessorDefinitions: List[str] = Factory(list)
    sourceFiles: List[str] = Factory(list)
    includeDirectories: List[str] = Factory(list)
Exemplo n.º 21
0
class BracketTracker:
    depth: int = 0
    bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = Factory(dict)
    delimiters: Dict[LeafID, Priority] = Factory(dict)
    previous: Optional[Leaf] = None

    def mark(self, leaf: Leaf) -> None:
        if leaf.type == token.COMMENT:
            return

        if leaf.type in CLOSING_BRACKETS:
            self.depth -= 1
            opening_bracket = self.bracket_match.pop((self.depth, leaf.type))
            leaf.opening_bracket = opening_bracket
        leaf.bracket_depth = self.depth
        if self.depth == 0:
            delim = is_delimiter(leaf)
            if delim:
                self.delimiters[id(leaf)] = delim
            elif self.previous is not None:
                if leaf.type == token.STRING and self.previous.type == token.STRING:
                    self.delimiters[id(self.previous)] = STRING_PRIORITY
                elif (
                    leaf.type == token.NAME
                    and leaf.value == 'for'
                    and leaf.parent
                    and leaf.parent.type in {syms.comp_for, syms.old_comp_for}
                ):
                    self.delimiters[id(self.previous)] = COMPREHENSION_PRIORITY
                elif (
                    leaf.type == token.NAME
                    and leaf.value == 'if'
                    and leaf.parent
                    and leaf.parent.type in {syms.comp_if, syms.old_comp_if}
                ):
                    self.delimiters[id(self.previous)] = COMPREHENSION_PRIORITY
                elif (
                    leaf.type == token.NAME
                    and leaf.value in LOGIC_OPERATORS
                    and leaf.parent
                ):
                    self.delimiters[id(self.previous)] = LOGIC_PRIORITY
        if leaf.type in OPENING_BRACKETS:
            self.bracket_match[self.depth, BRACKET[leaf.type]] = leaf
            self.depth += 1
        self.previous = leaf

    def any_open_brackets(self) -> bool:
        """Returns True if there is an yet unmatched open bracket on the line."""
        return bool(self.bracket_match)

    def max_priority(self, exclude: Iterable[LeafID] =()) -> int:
        """Returns the highest priority of a delimiter found on the line.

        Values are consistent with what `is_delimiter()` returns.
        """
        return max(v for k, v in self.delimiters.items() if k not in exclude)
Exemplo n.º 22
0
class TestResult(ExecutableItem):
    uuid = attrib(default=None)
    historyId = attrib(default=None)
    fullName = attrib(default=None)
    labels = attrib(default=Factory(list))
    links = attrib(default=Factory(list))

    def write(self, report_dir):
        _write(report_dir, self, TEST_CASE_PATTERN)
Exemplo n.º 23
0
class Attribute:
    """An attribute for an object. Can be marked as not to be dumped with the
    object by setting the same flag to False, and not to be visible to players
    by setting the visible flag to False."""

    value = attrib()
    description = attrib()
    type = attrib(default=Factory(lambda: str))
    save = attrib(default=Factory(lambda: True))
    visible = attrib(default=Factory(lambda: True))
Exemplo n.º 24
0
class KqlQuery:
    """KqlQuery definition."""

    name: str = ""
    query: str = ""
    description: str = ""
    data_source: str = ""
    data_families: List[DataFamily] = Factory(list)
    data_environments: List[DataEnvironment] = Factory(list)
    optional_params: List[str] = Factory(list)
Exemplo n.º 25
0
class KqlQuery(object):
    """KqlQuery definition."""

    name = attrib(default=None)
    query = attrib(default=None)
    description = attrib(default=None)
    data_source = attrib(default=None)
    data_families = attrib(default=Factory(list))
    data_environments = attrib(default=Factory(list))
    optional_params = attrib(default=Factory(list))
Exemplo n.º 26
0
class Item(MudBase):
    short_desc = field(default='', type=str)
    item_type = field(default=-1, type=int)
    extra_flags = field(default=0, type=int)
    wear_flags = field(default=0, type=WEAR_LOCATIONS)
    cost = field(default=0, type=int)
    level = field(default=0, type=int)
    weight = field(default=0, type=int)
    affected = attr(default=Factory(list))
    value = attr(default=Factory(list), type=List)
Exemplo n.º 27
0
class Item:
    """A menu item."""

    title = attrib()
    command = attrib()
    args = attrib(default=Factory(list))
    kwargs = attrib(default=Factory(dict))

    def dump(self):
        """Return this instance as a list."""
        return [self.title, self.command, self.args, self.kwargs]
Exemplo n.º 28
0
class IoCLookupParams:
    """IoC HTTP Lookup Params definition."""

    path: str = ""
    verb: str = "GET"
    full_url: bool = False
    headers: Dict[str, str] = Factory(dict)
    params: Dict[str, str] = Factory(dict)
    data: Dict[str, str] = Factory(dict)
    auth_type: str = ""
    auth_str: List[str] = Factory(list)
    sub_type: str = ""
Exemplo n.º 29
0
class ExecutableItem(object):
    name = attrib(default=None)
    status = attrib(default=None)
    statusDetails = attrib(default=None)
    stage = attrib(default=None)
    description = attrib(default=None)
    descriptionHtml = attrib(default=None)
    steps = attrib(default=Factory(list))
    attachments = attrib(default=Factory(list))
    parameters = attrib(default=Factory(list))
    start = attrib(default=None)
    stop = attrib(default=None)
Exemplo n.º 30
0
class window(object):
	title = attrib()
	width = attrib(default=Factory(lambda: 300))
	height = attrib(default=Factory(lambda: 200))

	def __attrs_post_init__(self):
		self.screen = pygame.display.set_mode((self.width, self.height))
		pygame.display.set_caption(self.title)

	def show(self):
		#show the window
		pygame.display.flip()