コード例 #1
0
ファイル: game.py プロジェクト: tundish/addisonarches
    def declare(self, data, loop=None):
        super().declare(data, loop)
        events = (i for i in self._services.values()
                   if isinstance(i, Persistent.RSON))
        for each in events:
            path = Persistent.make_path(
                Persistent.recent_slot(each.path)._replace(file=each.path.file)
            )
            fP = os.path.join(*path)
            with Expert.declaration(fP) as output:
                for i in data.get(each.attr, []):
                    try:
                        Assembly.dump(i, output, indent=0)
                    except Exception as e:
                        self._log.error(". ".join(getattr(e, "args", e) or e))
                    finally:
                        output.write("\n")

        pickles = (i for i in self._services.values()
                   if isinstance(i, Persistent.Pickled)
                   and data.get(i.name, False))
        for p in pickles:
            fP = os.path.join(*p.path)
            with open(fP, "wb") as fObj:
                pickle.dump(data[p.name], fObj, 4)
コード例 #2
0
ファイル: test_story.py プロジェクト: tundish/blue_monday_78
    def test_ready_narrator_01(self):
        Assembly.register(AssemblyTests.ForeignState)
        narrator = bluemonday78.story.build_narrator().set_state(
            AssemblyTests.ForeignState.hostile)
        self.assertTrue(hasattr(narrator, "memories"))
        self.assertIsInstance(narrator.memories, collections.deque)
        narrator.memories.extend(range(4))
        self.assertEqual(197801160800, narrator.state)
        self.assertEqual(4, len(narrator.memories))
        self.assertEqual(3, len(narrator._states))

        text = Assembly.dumps(narrator)
        clone = Assembly.loads(text)
        self.assertEqual(narrator.id, clone.id)
        self.assertTrue(hasattr(clone, "memories"))
        self.assertIsInstance(clone.memories, list)
        self.assertEqual(4, len(clone.memories))
        self.assertEqual(3, len(narrator._states))

        # Check state transfer
        self.assertEqual(197801160800, clone.state)
        clone.state = 0

        result = bluemonday78.story.build_narrator(id=None,
                                                   memories=clone.memories,
                                                   _states=clone._states)
        self.assertNotEqual(clone.id, result.id)
        self.assertTrue(hasattr(result, "memories"))
        self.assertIsInstance(result.memories, collections.deque)
        self.assertEqual(4, len(result.memories))
        self.assertEqual(0, result.state)
        self.assertEqual(3, len(result._states))
        self.assertEqual(AssemblyTests.ForeignState.hostile,
                         result.get_state(AssemblyTests.ForeignState))
コード例 #3
0
 def test_nested_object_roundtrip(self):
     obj = Assembly.loads(AssemblyTester.data)
     text = textwrap.dedent(Assembly.dumps(obj))
     rv = Assembly.loads(text)
     self.assertEqual(obj.bucket, rv.bucket)
     self.assertEqual(obj.wheel, rv.wheel)
     self.assertEqual(obj.handles, rv.handles)
コード例 #4
0
 def test_nested_object_dumps(self):
     obj = Assembly.loads(AssemblyTester.data)
     text = Assembly.dumps(obj, indent=4)
     self.assertEqual(
         len(AssemblyTester.data.strip()),
         len(text.strip())
     )
コード例 #5
0
 def test_nested_object_roundtrip(self):
     obj = Assembly.loads(AssemblyTester.data)
     text = textwrap.dedent(Assembly.dumps(obj))
     rv = Assembly.loads(text)
     self.assertEqual(obj.bucket, rv.bucket)
     self.assertEqual(obj.wheel, rv.wheel)
     self.assertEqual(obj.handles, rv.handles)
コード例 #6
0
 def test_assemble_spot(self):
     obj = list(Spot)[0]
     data = Assembly.dumps(obj)
     self.assertTrue(data)
     rv = Assembly.loads(data)
     self.assertIsInstance(rv, Spot)
     self.assertEqual(obj.value, rv.value)
コード例 #7
0
def cgi_producer(args, stream=None):
    log_manager = LogManager()
    log = log_manager.get_logger("turberfield")
    log.info(args)
    try:
        handler = CGIHandler(Terminal(stream=stream),
                             None if args.db == "None" else args.db,
                             float(args.pause), float(args.dwell))
    except Exception as e:
        log.error(e)
        raise

    print("Content-type:text/event-stream", file=handler.terminal.stream)
    print(file=handler.terminal.stream)

    folders, references = resolve_objects(args)
    Assembly.register(*(i if isinstance(i, type) else type(i)
                        for i in references))
    log.info(folders)
    try:
        yield from rehearse(folders, references, handler, int(args.repeat),
                            int(args.roles), args.strict)
    except Exception as e:
        log.error(e)
        raise
    else:
        log.debug(references)
コード例 #8
0
 def test_volume_roundtrip(self):
     # https://bugs.python.org/issue23572
     # requires Python 3.5.1
     vol = Volume.bundle
     text = Assembly.dumps(vol)
     rv = Assembly.loads(text)
     self.assertEqual(vol, rv)
コード例 #9
0
 def test_round_trip_assembly(self):
     Assembly.register(Player)
     player = Player(name="Mr Dick Turpin").set_state(12)
     text = Assembly.dumps(player)
     clone = Assembly.loads(text)
     self.assertEqual(player.id, clone.id)
     self.assertEqual(player.name, clone.name)
     self.assertEqual(player.state, clone.state)
コード例 #10
0
 def test_uuid(self):
     # From Python 3.8 a UUID object has no __dict__
     self.assertNotIn(uuid.UUID, Assembly.encoding)
     self.assertNotIn(uuid.UUID, Assembly.decoding)
     Assembly.register(uuid.UUID)
     obj = uuid.uuid4()
     rv = Assembly.dumps(obj)
     self.assertIn(uuid.UUID, Assembly.encoding)
     self.assertIn("uuid.UUID", Assembly.decoding)
コード例 #11
0
    def test_numeric_types(self):
        val = decimal.Decimal("3.14")
        rv = Assembly.dumps(val)
        self.assertEqual("3.14", rv)
        self.assertEqual(val, Assembly.loads(rv))

        val = complex("3+14j")
        rv = Assembly.dumps(val)
        self.assertEqual('"(3+14j)"', rv)
        self.assertEqual(val, complex(Assembly.loads(rv).replace('"', "")))
コード例 #12
0
ファイル: test_story.py プロジェクト: tundish/blue_monday_78
    def test_assembly(self):
        narrator = bluemonday78.story.build_narrator()
        ensemble = bluemonday78.story.ensemble(narrator)
        text = Assembly.dumps(ensemble)
        clone = Assembly.loads(text)

        self.assertEqual(
            set(group_by_type(ensemble).keys()),
            set(group_by_type(clone).keys()),
            "Check all ensemble classes permit re-assembly (DataObject)")
コード例 #13
0
ファイル: expert.py プロジェクト: tundish/turberfield-utils
    def declare(self, data, loop=None):
        """
        :param data: data to be published
        :type data: a dictionary

        Invoke this method from within
        :py:meth:`__call__ <turberfield.utils.expert.Expert.__call__>`
        to publish data via the class-defined interface.

        The keyword arguments previously supplied to
        :py:meth:`__init__ <turberfield.utils.expert.Expert.__init__>`
        determine what attributes are published, according to the following
        mechanisms:

        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | Interface type                                                    | Publishing mechanism                                              |
        +===================================================================+===================================================================+
        | :py:class:`Attribute <turberfield.utils.expert.Expert.Attribute>` | ``<Subclass>.public.<name>`` mirrors the data value.              |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`Event <turberfield.utils.expert.Expert.Event>`         | ``<Subclass>.public.<name>`` is set or cleared by the data value. |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`RSON <turberfield.utils.expert.Expert.RSON>`           | ``RSON.dst`` is the file path to the data in RSON format.         |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`HATEOAS <turberfield.utils.expert.Expert.HATEOAS>`     | ``HATEOAS.dst`` is the file path to the data as a JSON web page.  |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        """  # noqa: E501
        class_ = self.__class__
        kwargs = defaultdict(None)
        for name, service in self._services.items():
            if isinstance(service, Expert.Attribute):
                kwargs[service.name] = data[service.name]
            elif isinstance(service, Expert.Event):
                event = kwargs[service.name] = (
                    getattr(class_.public, service.name) or
                    asyncio.Event(loop=loop)
                )
                if data[service.name]:
                    event.set()
                else:
                    event.clear()
            elif isinstance(service, Expert.RSON):
                with Expert.declaration(service.dst) as output:
                    for i in data.get(service.attr, []):
                        Assembly.dump(i, output, indent=0)
                        output.write("\n")
            elif isinstance(service, Expert.HATEOAS):
                page = class_.page()
                page.info["ts"] = time.time()
                page.items[:] = data.get(service.attr, [])
                with Expert.declaration(service.dst) as output:
                    Assembly.dump(vars(page), output, indent=4)

        class_.public = class_.public._replace(**kwargs)
コード例 #14
0
ファイル: expert.py プロジェクト: tundish/turberfield-utils
    def declare(self, data, loop=None):
        """
        :param data: data to be published
        :type data: a dictionary

        Invoke this method from within
        :py:meth:`__call__ <turberfield.utils.expert.Expert.__call__>`
        to publish data via the class-defined interface.

        The keyword arguments previously supplied to
        :py:meth:`__init__ <turberfield.utils.expert.Expert.__init__>`
        determine what attributes are published, according to the following
        mechanisms:

        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | Interface type                                                    | Publishing mechanism                                              |
        +===================================================================+===================================================================+
        | :py:class:`Attribute <turberfield.utils.expert.Expert.Attribute>` | ``<Subclass>.public.<name>`` mirrors the data value.              |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`Event <turberfield.utils.expert.Expert.Event>`         | ``<Subclass>.public.<name>`` is set or cleared by the data value. |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`RSON <turberfield.utils.expert.Expert.RSON>`           | ``RSON.dst`` is the file path to the data in RSON format.         |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        | :py:class:`HATEOAS <turberfield.utils.expert.Expert.HATEOAS>`     | ``HATEOAS.dst`` is the file path to the data as a JSON web page.  |
        +-------------------------------------------------------------------+-------------------------------------------------------------------+
        """
        class_ = self.__class__
        kwargs = defaultdict(None)
        for name, service in self._services.items():
            if isinstance(service, Expert.Attribute):
                kwargs[service.name] = data[service.name]
            elif isinstance(service, Expert.Event):
                event = kwargs[service.name] = (
                    getattr(class_.public, service.name)
                    or asyncio.Event(loop=loop))
                if data[service.name]:
                    event.set()
                else:
                    event.clear()
            elif isinstance(service, Expert.RSON):
                with Expert.declaration(service.dst) as output:
                    for i in data.get(service.attr, []):
                        Assembly.dump(i, output, indent=0)
                        output.write("\n")
            elif isinstance(service, Expert.HATEOAS):
                page = class_.page()
                page.info["ts"] = time.time()
                page.items[:] = data.get(service.attr, [])
                with Expert.declaration(service.dst) as output:
                    Assembly.dump(vars(page), output, indent=4)

        class_.public = class_.public._replace(**kwargs)
コード例 #15
0
 def test_belt_roundtrip(self):
     inventory = Counter(
         itertools.chain((String(1), Glyph("snake")),
         itertools.repeat(Shell("white"), 64))
     )
     inventory[Wampum.build(inventory)] += 1
     belt = Belt.build(inventory, maxlen=3)
     text = Assembly.dumps(belt)
     obj = Assembly.loads(text)
     self.assertEqual(
         66, sum(dict(obj.requirements()).values())
     )
     self.assertEqual(belt.memory, obj.memory)
コード例 #16
0
ファイル: udp.py プロジェクト: tundish/turberfield-ipc
    def __call__(self, token=None):
        token = token or self.token
        while True:
            try:
                job = yield from self.down.get()

                poa, msg = self.hop(token, job, policy="udp")
                if job.header.via is not None:
                    # User-defined route
                    hop = next(Flow.find(
                        token,
                        application=job.header.via.application,
                        policy="udp"),
                    None)
                    poa = Flow.inspect(hop)

                if poa is None:
                    warnings.warn("Message expired.")
                    continue

                if msg is not None:
                    remote_addr = (poa.addr, poa.port)
                    data = Assembly.dumps(msg)
                    packet = dumpb(data)
                    self.transport.sendto(packet, remote_addr)
                else:
                    warnings.warn("No message from hop.")

            except concurrent.futures.CancelledError:
                break
            except Exception as e:
                warnings.warn(repr(getattr(e, "args", e) or e))
                continue
コード例 #17
0
 def test_loads_bad_header(self):
     data = textwrap.dedent("""
     {
     "_type": "turberfield.ipc.message.Message",
     "header": {
         "_type": "turberfield.ipc.message.Header",
         "id": "aa27e84fa93843658bfcd5b4f9ceee4f",
         "src": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.sender"
         },
         "dst": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.receiver"
         },
         "hMax": 3,
         "hop": 0
     },
     "payload": []
     }
     """)
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter("always")
         msg = Assembly.loads(data)
         self.assertEqual(1, len(w))
         self.assertTrue(
             issubclass(w[-1].category, UserWarning))
         self.assertIn("Parameter mismatch", str(w[-1].message))
コード例 #18
0
    def __call__(self, token=None):
        token = token or self.token
        while True:
            try:
                job = yield from self.down.get()

                poa, msg = self.hop(token, job, policy="udp")
                if job.header.via is not None:
                    # User-defined route
                    hop = next(
                        Flow.find(token,
                                  application=job.header.via.application,
                                  policy="udp"), None)
                    poa = Flow.inspect(hop)

                if poa is None:
                    warnings.warn("Message expired.")
                    continue

                if msg is not None:
                    remote_addr = (poa.addr, poa.port)
                    data = Assembly.dumps(msg)
                    packet = dumpb(data)
                    self.transport.sendto(packet, remote_addr)
                else:
                    warnings.warn("No message from hop.")

            except concurrent.futures.CancelledError:
                break
            except Exception as e:
                warnings.warn(repr(getattr(e, "args", e) or e))
                continue
コード例 #19
0
def presenter(args):
    handler = TerminalHandler(Terminal(), args.db, args.pause, args.dwell)
    folders, references = resolve_objects(args)
    Assembly.register(*(i if isinstance(i, type) else type(i)
                        for i in references))

    if args.log_level != logging.DEBUG:
        with handler.terminal.fullscreen():
            for folder in folders:
                yield from rehearse(folder, references, handler, args.repeat,
                                    args.roles, args.strict)
                input("Press return.")
    else:
        for folder in folders:
            yield from rehearse(folder, references, handler, args.repeat,
                                args.roles, args.strict)
コード例 #20
0
 def test_loads_bad_header(self):
     data = textwrap.dedent("""
     {
     "_type": "turberfield.ipc.message.Message",
     "header": {
         "_type": "turberfield.ipc.message.Header",
         "id": "aa27e84fa93843658bfcd5b4f9ceee4f",
         "src": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.sender"
         },
         "dst": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.receiver"
         },
         "hMax": 3,
         "hop": 0
     },
     "payload": []
     }
     """)
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter("always")
         msg = Assembly.loads(data)
         self.assertEqual(1, len(w))
         self.assertTrue(issubclass(w[-1].category, UserWarning))
         self.assertIn("Parameter mismatch", str(w[-1].message))
コード例 #21
0
 def test_nested_object_extraloads(self):
     data = AssemblyTester.data[:-3] + textwrap.dedent("""
     ,{
         "_type": "turberfield.utils.test.test_assembly.Handle",
         "length": 80,
         "grip": {
             "_type": "turberfield.utils.test.test_assembly.Grip",
             "length": 15,
             "colour": {
                 "_type": "turberfield.utils.test.test_assembly.Colour",
                 "name": "red",
                 "value": [
                     0,
                     255,
                     0
                 ]
             }
         }
     }
     ]}""")
     rv = Assembly.loads(data)
     self.assertIsInstance(rv, Wheelbarrow)
     self.assertIsInstance(rv.handles, deque)
     self.assertEqual(2, len(rv.handles))
     self.assertEqual(Wheelbarrow.Colour.green, rv.handles[0].grip.colour)
     self.assertEqual(Wheelbarrow.Colour.red, rv.handles[1].grip.colour)
コード例 #22
0
def create_udp_node(loop, token, down, up):
    """
    Creates a node which uses UDP for inter-application messaging

    """
    assert loop.__class__.__name__.endswith("SelectorEventLoop")
 
    services = []
    types = Assembly.register(Policy)
    policies = Policy(poa=["udp"], role=[], routing=["application"])
    refs = match_policy(token, policies) or Flow.create(token, **policies._asdict())
    for ref in refs:
        obj = Flow.inspect(ref)
        key = next(k for k, v in policies._asdict().items() if ref.policy in v) 
        field = getattr(policies, key)
        field[field.index(ref.policy)] = obj
        try:
            services.append(obj.mechanism)
        except AttributeError:
            warnings.warn("Policy '{}' lacks a mechanism".format(ref.policy))

    udp = next(iter(policies.poa))
    Mix = type("UdpNode", tuple(services), {})
    transport, protocol = loop.run_until_complete(
        loop.create_datagram_endpoint(
            lambda:Mix(loop, token, types, down=down, up=up, **policies._asdict()),
            local_addr=(udp.addr, udp.port)
        )
    )
    return protocol
コード例 #23
0
 def test_wampum_roundtrip(self):
     inventory = Counter(
         itertools.chain((String(1), Glyph("snake")),
         itertools.repeat(Shell("white"), 64))
     )
     obj = Wampum.build(inventory)
     text = Assembly.dumps(obj)
コード例 #24
0
 def test_nested_object_extraloads(self):
     data = AssemblyTester.data[:-3] + textwrap.dedent("""
     ,{
         "_type": "turberfield.utils.test.test_assembly.Handle",
         "length": 80,
         "grip": {
             "_type": "turberfield.utils.test.test_assembly.Grip",
             "length": 15,
             "colour": {
                 "_type": "turberfield.utils.test.test_assembly.Colour",
                 "name": "red",
                 "value": [
                     0,
                     255,
                     0
                 ]
             }
         }
     }
     ]}""")
     rv = Assembly.loads(data)
     self.assertIsInstance(rv, Wheelbarrow)
     self.assertIsInstance(rv.handles, deque)
     self.assertEqual(2, len(rv.handles))
     self.assertEqual(Wheelbarrow.Colour.green, rv.handles[0].grip.colour)
     self.assertEqual(Wheelbarrow.Colour.red, rv.handles[1].grip.colour)
コード例 #25
0
    def datagram_received(self, data, addr):
        """
        Routing only. Provides no upward service.

        """
        packet = self.decoder.send(data)
        if packet is None:
            return (None, None)

        msg = Assembly.loads(packet)
        poa, msg = self.hop(self.token, msg, policy="udp")
        if poa is not None:
            remote_addr = (poa.addr, poa.port)
            data = Assembly.dumps(msg)
            packet = dumpb(data)
            self.transport.sendto(packet, remote_addr)
        return (poa, msg)
コード例 #26
0
ファイル: udp.py プロジェクト: tundish/turberfield-ipc
    def datagram_received(self, data, addr):
        """
        Routing only. Provides no upward service.

        """
        packet = self.decoder.send(data)
        if packet is None:
            return (None, None)

        msg = Assembly.loads(packet)
        poa, msg = self.hop(self.token, msg, policy="udp")
        if poa is not None:
            remote_addr = (poa.addr, poa.port)
            data = Assembly.dumps(msg)
            packet = dumpb(data)
            self.transport.sendto(packet, remote_addr)
        return (poa, msg)
コード例 #27
0
 def test_nested_object_loads(self):
     rv = Assembly.loads(AssemblyTester.data)
     self.assertIsInstance(rv, Wheelbarrow)
     self.assertEqual(45, rv.bucket.capacity)
     self.assertIsInstance(rv.wheel.rim.dia, Decimal)
     self.assertEqual(30, rv.wheel.tyre.pressure)
     self.assertIsInstance(rv.handles, deque)
     self.assertEqual(2, len(rv.handles))
     self.assertEqual(Wheelbarrow.Colour.green, rv.handles[0].grip.colour)
コード例 #28
0
 def test_nested_object_loads(self):
     rv = Assembly.loads(AssemblyTester.data)
     self.assertIsInstance(rv, Wheelbarrow)
     self.assertEqual(45, rv.bucket.capacity)
     self.assertIsInstance(rv.wheel.rim.dia, Decimal)
     self.assertEqual(30, rv.wheel.tyre.pressure)
     self.assertIsInstance(rv.handles, deque)
     self.assertEqual(2, len(rv.handles))
     self.assertEqual(Wheelbarrow.Colour.green, rv.handles[0].grip.colour)
コード例 #29
0
async def post_titles(request):
    config = next(iter(request.app["config"]), None)
    data = await request.post()
    assembly_url = data.get("assembly_url")
    ensemble = []
    if assembly_url and config and config.getboolean(
            "assembly", "enable_load", fallback=False):
        if not Presenter.validation["url"].match(assembly_url):
            raise web.HTTPUnauthorized(reason="User requested invalid URL.")

        try:
            async with request.app["client"].get(assembly_url,
                                                 trace_request_ctx={
                                                     "log_name": "app.client"
                                                 }) as response:

                if response.status != 200:
                    raise web.HTTPUnauthorized(reason=response.reason)

                text = await (response.text())
                try:
                    assembly = Assembly.loads(text)
                    ensemble = assembly.get("ensemble")
                except Exception as e:
                    request.app["log"].error(e)
                    raise web.HTTPUnauthorized(reason="Invalid data.")

        except (
                aiohttp.ClientResponseError,
                aiohttp.ClientConnectionError,
                aiohttp.ClientPayloadError,
                asyncio.TimeoutError,
        ) as e:
            request.app["log"].error(e)

        try:
            clone = next(i for i in reversed(ensemble)
                         if isinstance(i, Narrator))
            narrator = bluemonday78.story.build_narrator(
                id=None, memories=clone.memories, _states=clone._states)
            ensemble.remove(clone)
            ensemble.append(narrator)
        except:
            ensemble = None

    if not ensemble:
        narrator = bluemonday78.story.build_narrator()
        ensemble = bluemonday78.story.ensemble(narrator)
    else:
        request.app["log"].info("Load successful from assembly")

    presenter = Presenter(None, ensemble)
    presenter.log.debug(narrator)
    request.app["sessions"][narrator.id] = presenter
    request.app["log"].info("session: {0.id.hex}".format(narrator))
    raise web.HTTPFound("/{0.id.hex}".format(narrator))
コード例 #30
0
 def setUp(self):
     types = Assembly.register(Wheelbarrow,
                               Wheelbarrow.Brick,
                               Wheelbarrow.Bucket,
                               Wheelbarrow.Colour,
                               Wheelbarrow.Grip,
                               Wheelbarrow.Handle,
                               Wheelbarrow.Rim,
                               Wheelbarrow.Tyre,
                               Wheelbarrow.Wheel,
                               namespace="turberfield")
     self.assertEqual(9, len(types))
コード例 #31
0
    def handle_line(self, obj):
        if obj.persona is None:
            return obj

        print("event: line",
              "data: {0}\n".format(Assembly.dumps(obj)),
              sep="\n",
              end="\n",
              file=self.terminal.stream)
        self.terminal.stream.flush()
        interval = self.pause + self.dwell * obj.text.count(" ")
        time.sleep(interval)
        return obj
コード例 #32
0
 def setUp(self):
     types = Assembly.register(
         Wheelbarrow,
         Wheelbarrow.Brick,
         Wheelbarrow.Bucket,
         Wheelbarrow.Colour,
         Wheelbarrow.Grip,
         Wheelbarrow.Handle,
         Wheelbarrow.Rim,
         Wheelbarrow.Tyre,
         Wheelbarrow.Wheel,
         namespace="turberfield"
     )
     self.assertEqual(9, len(types))
コード例 #33
0
async def get_assembly(request):
    config = next(iter(request.app["config"]), None)
    if not (config
            and config.getboolean("assembly", "enable_dump", fallback=False)):
        raise web.HTTPUnauthorized(reason="Operation not enabled.")

    uid = uuid.UUID(hex=request.match_info["session"])
    try:
        presenter = request.app["sessions"][uid]
    except KeyError:
        raise web.HTTPUnauthorized(
            reason="Session {0!s} not found.".format(uid))
    else:
        return web.Response(text=Assembly.dumps(presenter.assembly),
                            content_type="application/json")
コード例 #34
0
 def test_loads_empty_payload(self):
     data = textwrap.dedent("""
     {
     "_type": "turberfield.ipc.message.Message",
     "header": {
         "_type": "turberfield.ipc.message.Header",
         "id": "aa27e84fa93843658bfcd5b4f9ceee4f",
         "src": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.sender"
         },
         "dst": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.receiver"
         },
         "hMax": 3,
         "via": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.hub"
         },
         "hop": 0
     },
     "payload": []
     }
     """)
     msg = Assembly.loads(data)
     self.assertIsInstance(msg, turberfield.ipc.message.Message)
     self.assertIsInstance(msg.header, turberfield.ipc.message.Header)
     self.assertIsInstance(msg.header.src, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.sender",
                      msg.header.src.application)
     self.assertIsInstance(msg.header.dst, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.receiver",
                      msg.header.dst.application)
     self.assertIsInstance(msg.header.via, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.hub",
                      msg.header.via.application)
     self.assertIsInstance(msg.payload, list)
     self.assertFalse(msg.payload)
コード例 #35
0
 def test_loads_empty_payload(self):
     data = textwrap.dedent("""
     {
     "_type": "turberfield.ipc.message.Message",
     "header": {
         "_type": "turberfield.ipc.message.Header",
         "id": "aa27e84fa93843658bfcd5b4f9ceee4f",
         "src": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.sender"
         },
         "dst": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.receiver"
         },
         "hMax": 3,
         "via": {
             "_type": "turberfield.ipc.types.Address",
             "namespace": "turberfield",
             "user": "******",
             "service": "test",
             "application": "turberfield.ipc.demo.hub"
         },
         "hop": 0
     },
     "payload": []
     }
     """)
     msg = Assembly.loads(data)
     self.assertIsInstance(msg, turberfield.ipc.message.Message)
     self.assertIsInstance(msg.header, turberfield.ipc.message.Header)
     self.assertIsInstance(msg.header.src, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.sender", msg.header.src.application)
     self.assertIsInstance(msg.header.dst, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.receiver", msg.header.dst.application)
     self.assertIsInstance(msg.header.via, turberfield.ipc.types.Address)
     self.assertEqual("turberfield.ipc.demo.hub", msg.header.via.application)
     self.assertIsInstance(msg.payload, list)
     self.assertFalse(msg.payload)
コード例 #36
0
    def handle_property(self, obj):
        self.log_manager = LogManager()
        self.log = self.log_manager.get_logger("turberfield")
        self.log.info(obj)
        if obj.object is not None:
            try:
                setattr(obj.object, obj.attr, obj.val)
            except AttributeError as e:
                self.log.error(". ".join(getattr(e, "args", e) or e))

            print("event: property",
                  "data: {0}\n".format(Assembly.dumps(obj)),
                  sep="\n",
                  end="\n",
                  file=self.terminal.stream)
            self.terminal.stream.flush()
        time.sleep(self.pause)
        return obj
コード例 #37
0
 def test_shell_roundtrip(self):
     obj = Shell("pink")
     text = Assembly.dumps(obj)
     rv = Assembly.loads(text)
     self.assertEqual(obj, rv)
コード例 #38
0
ファイル: types.py プロジェクト: tundish/addisonarches
    Swarfega and blue roll. She has a limited capacity for storing
    recovered fuel; she will consider selling petrol or diesel to
    you if she trusts you.

    """
    pass

class MarketStall(Trader):
    """
    {proprietor.name} has a stall on the market. He'll buy anything
    but only at a rock-bottom price.

    """
    pass

class Antiques(Trader):
    """
    {proprietor.name} runs an antique shop. She's always looking
    for fabrics which she cuts up and sells as rare designs. She'll
    also buy picture frames if they're cheap and contemporary.

    """
    pass

Assembly.register(
    Name,
    Ownership, Presence, Vocabulary,
    Character, Commodity, Location, Plank, Table,
    FormB107, Keys, Location, Prisoner, PrisonOfficer, PrisonVisitor,
)
コード例 #39
0
 def setUpClass(cls):
     Assembly.register(
         Belt, Glyph, Length, Pellets, Shell, String, Wampum
     )
コード例 #40
0
 def test_string_roundtrip(self):
     obj = String(3)
     text = Assembly.dumps(obj)
     rv = Assembly.loads(text)
     self.assertEqual(obj, rv)
コード例 #41
0
ファイル: valuation.py プロジェクト: tundish/addisonarches
        elif isinstance(obj, (Ask, Bid)):
            series = self[commodity]
            series.append(obj)
        else:
            raise NotImplementedError

        return self.estimate(series)

    def consider(self, commodity, offer:set([Ask, Bid]), constraint=1.0):
        estimate = self.estimate(self[commodity])
        if isinstance(offer, Ask):
            if offer.value < estimate.value or random.random() >= constraint:
                return self.commit(commodity, offer)
            else:
                return estimate
        elif isinstance(offer, Bid):
            if offer.value > estimate.value or random.random() <= constraint:
                return self.commit(commodity, offer)
            else:
                return estimate
        else:
            raise NotImplementedError

    def setdefault(self, key, default=None):
        raise NotImplementedError

    def update(self, other):
        raise NotImplementedError

Assembly.register(Ask, Bid, Note, Valuation)
コード例 #42
0
def cgi_consumer(args):
    folders, references = resolve_objects(args)
    Assembly.register(*(i if isinstance(i, type) else type(i)
                        for i in references))

    resources = list(
        rehearse(folders,
                 references,
                 yield_resources,
                 repeat=0,
                 roles=args.roles,
                 strict=args.strict))
    links = "\n".join('<link ref="prefetch" href="/{0}">'.format(i)
                      for i in resources)
    params = [(k, v) for k, v in vars(args).items()
              if k not in ("folder", "session")]
    params.append(("session", uuid.uuid4().hex))
    params.extend([("folder", i) for i in args.folder])
    opts = urllib.parse.urlencode(params)
    url = "http://localhost:{0}/{1}/turberfield-rehearse?{2}".format(
        args.port, args.locn, opts)
    rv = textwrap.dedent("""
        Content-type:text/html

        <!doctype html>
        <html lang="en">
        <head>
        <meta charset="utf-8" />
        <title>Rehearsal</title>
        {links}
        <style>
        #line {{
            font-family: "monospace";
        }}
        #line .persona::after {{
            content: ": ";
        }}
        #event {{
            font-style: italic;
        }}
        </style>
        </head>
        <body class="loading">
        <h1>...</h1>
        <blockquote id="line">
        <header class="persona"></header>
        <p class="data"></p>
        </blockquote>
        <audio id="cue"></audio>
        <span id="event"></span>
        <script>
            if (!!window.EventSource) {{
                var source = new EventSource("{url}");
            }} else {{
                alert("Your browser does not support Server-Sent Events.");
            }}

            source.addEventListener("audio", function(e) {{
                console.log(e);
                var audio = document.getElementById("cue");
                audio.setAttribute("src", e.data);
                audio.currentTime = 0;
                audio.play();
            }}, false);

            source.addEventListener("line", function(e) {{
                console.log(e);
                var event = document.getElementById("event");
                event.innerHTML = "";
                var obj = JSON.parse(e.data);
                var quote = document.getElementById("line");
                var speaker = quote.getElementsByClassName("persona")[0];
                var line = quote.getElementsByClassName("data")[0];

                speaker.innerHTML = obj.persona.name.firstname;
                speaker.innerHTML += " ";
                speaker.innerHTML += obj.persona.name.surname;
                line.innerHTML = obj.html;

            }}, false);

            source.addEventListener("memory", function(e) {{
                var obj = JSON.parse(e.data);
                var event = document.getElementById("event");
                event.innerHTML = obj.html;
            }}, false);

            source.addEventListener("property", function(e) {{
                var obj = JSON.parse(e.data);
                var event = document.getElementById("event");
                event.innerHTML = "<";
                event.innerHTML += obj.object._name;
                event.innerHTML += ">.";
                event.innerHTML += obj.attr;
                event.innerHTML += " = ";
                event.innerHTML += obj.val.name || obj.val;
            }}, false);

            source.addEventListener("open", function(e) {{
                console.log("Connection was opened.");
            }}, false);

            source.addEventListener("error", function(e) {{
                console.log("Error: connection lost.");
            }}, false);

        </script>
        </body>
        </html>
    """).format(links=links, url=url).lstrip()
    return rv
コード例 #43
0
ファイル: types.py プロジェクト: tundish/turberfield-dialogue
    def nickname(self):
        return random.choice(self.name.nicknames)


class Stateful:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._states = {}

    @property
    def state(self):
        return self.get_state()

    @state.setter
    def state(self, value):
        return self.set_state(value)

    def set_state(self, *args):
        for value in args:
            self._states[type(value).__name__] = value
        return self

    def get_state(self, typ=int, default=0):
        return self._states.get(typ.__name__, default)

class Player(Persona, Stateful):
    pass

Assembly.register(Name, type(uuid.uuid4()))
コード例 #44
0
ファイル: business.py プロジェクト: tundish/addisonarches
                    valuation = self.book.consider(
                        type(focus), offer, constraint=0
                    )
                    yield Trader.Patter(self.proprietor, (
                        "I can go to "
                        "{0.currency}{0.value:.0f}.".format(valuation)
                    ))
                else:
                    yield Trader.Patter(self.proprietor, (
                        "I'll agree on "
                        "{0.currency}{0.value}.".format(offer)
                    ))
                    asset = Asset(focus, None, ts)
                    picks = game.businesses[0].retrieve(asset)
                    quantity = sum(i[1] for i in picks)
                    price = quantity * offer.value
                    self.store(
                        Asset(focus, quantity, ts)
                    )
                    self.tally -= price
                    game.businesses[0].tally += price
                    game.drama = None
            except (TypeError, NotImplementedError) as e:
                # No offer yet
                yield Trader.Patter(
                    self.proprietor,
                    "How much are you asking for a {0.label}?".format(focus)
                )

Assembly.register(Buying, Selling, Trader.Patter)
コード例 #45
0
ファイル: inventory.py プロジェクト: tundish/addisonarches
    slab = 24e-3
    case = 16e-3
    bundle = 8e-3
    tray = 4e-3
    carton = 2e-3
    brick = 1.5e-3
    bottle = 1e-3
    litre = 1e-3
    pack = 5e-4
    zero = 0

    @classmethod
    def factory(cls, name=None, **kwargs):
        return cls[name]


class Inventory:

    def __init__(self, capacity):
        self.capacity = capacity
        self.contents = Counter()

    @property
    def constraint(self) -> float:
        return sum(
            getattr(c.volume, "value", c.volume) * n
            for c, n in self.contents.items()
        ) / self.capacity

Assembly.register(Volume)
コード例 #46
0
ファイル: icons.py プロジェクト: tundish/addisonarches
# encoding: UTF-8

__doc__ = """
This module was generated by turberfield.ops.svgforger:

fontforge /home/boss/src/turberfield-ops/turberfield/ops/svgforger.py --name=addisonarches \
--prefix=diorama --output=~/src/addisonarches/addisonarches/web/static \
/home/boss/src/addisonarches/assets/formb107.svg \
/home/boss/src/addisonarches/assets/keys.svg \
/home/boss/src/addisonarches/assets/prisoner.svg \
/home/boss/src/addisonarches/assets/prisonofficer.svg \
/home/boss/src/addisonarches/assets/prisonvisitor.svg

"""

from collections import namedtuple
from turberfield.utils.assembly import Assembly

Icon = namedtuple("Icon", ["font", "prefix", "name", "ordinal"])

icons = [
    Icon("addisonarches", "diorama", "formb107", 350),
    Icon("addisonarches", "diorama", "keys", 351),
    Icon("addisonarches", "diorama", "prisoner", 352),
    Icon("addisonarches", "diorama", "prisonofficer", 353),
    Icon("addisonarches", "diorama", "prisonvisitor", 354),
]

Assembly.register(Icon)

コード例 #47
0
ファイル: types.py プロジェクト: tundish/turberfield-ipc
# 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 turberfield.  If not, see <http://www.gnu.org/licenses/>.

from collections import namedtuple

from turberfield.utils.assembly import Assembly

Address = namedtuple(
    "Address",
    ["namespace", "user", "service", "application"]
)
Address.__doc__ = """`{}`

A semantically hierarchical address for distributed networking.

    namespace
        Specifies the domain within which the address names are valid.
    user
        A unique name of trust within the network.
    service
        Identifies a currently operating instantiation of the network.
    application
        The name of the node endpoint.

""".format(Address.__doc__)

Assembly.register(Address)
コード例 #48
0
        if len(text
               ) not in formats and min(formats) < len(text) < max(formats):
            text = text + "0"
            mult = 10
        else:
            mult = 1
        try:
            format_string, span = formats[len(text)]
        except KeyError:
            return text, None
        else:
            return datetime.datetime.strptime(text, format_string), mult * span

    @property
    def clock(self):
        text = str(self.get_state(int))
        ts, span = self.parse_timespan(text)
        return ts

    @clock.setter
    def clock(self, hours=1):
        try:
            td = datetime.timedelta(hours=hours)
            ts = self.clock + td
            self.set_state(int(ts.strftime(self.state_format)))
        finally:
            return self.clock


Assembly.register(Look, Mode, Trade, Spot, Character, Location, Narrator)
コード例 #49
0
 def test_nested_object_dumps(self):
     obj = Assembly.loads(AssemblyTester.data)
     text = Assembly.dumps(obj, indent=4)
     self.assertEqual(len(AssemblyTester.data.strip()), len(text.strip()))
コード例 #50
0
ファイル: logic.py プロジェクト: tundish/turberfield-dialogue
from turberfield.dialogue.types import Stateful
from turberfield.utils.assembly import Assembly

__doc__ = """
A simple drama for demonstration.

"""


class Animal(Stateful, Persona):
    pass

class Tool(Stateful, Persona):
    pass

def ensemble():
    return [
        Animal(name="Itchy").set_state(1),
        Animal(name="Scratchy").set_state(1),
        Tool(name="Ol' Rusty Chopper").set_state(1),
    ]

references = ensemble()

folder = SceneScript.Folder(
    "turberfield.dialogue.sequences.battle",
    __doc__, None, ["combat.rst"], None
)

Assembly.register(Animal, Tool)
コード例 #51
0
    def cast(self, mapping):
        """Allocate the scene script a cast of personae for each of its entities.

        :param mapping: A dictionary of {Entity, Persona}
        :return: The SceneScript object.

        """
        # See 'citation' method in
        # http://docutils.sourceforge.net/docutils/parsers/rst/states.py
        for c, p in mapping.items():
            self.doc.note_citation(c)
            self.doc.note_explicit_target(c, c)
            c.persona = p
            self.log.debug(
                "{0} to be played by {1}".format(c["names"][0].capitalize(),
                                                 p), {"path": self.fP})
        return self

    def run(self):
        """Parse the script file.

        :rtype: :py:class:`~turberfield.dialogue.model.Model`
        """
        model = Model(self.fP, self.doc)
        self.doc.walkabout(model)
        return model


Assembly.register(Model.Audio, Model.Line, Model.Memory, Model.Property,
                  Model.Still, Model.Video)
コード例 #52
0
 def test_glyph_roundtrip(self):
     obj = Glyph("eagle")
     text = Assembly.dumps(obj)
     rv = Assembly.loads(text)
     self.assertEqual(obj, rv)
コード例 #53
0
ファイル: game.py プロジェクト: tundish/addisonarches
    options = Game.options(Game.Player(user, name), parent=parent)
    game = Game(
        Game.Player(user, name),
        addisonarches.scenario.easy.businesses[:],
        clock,
        token,
        up,
        down=down,
        loop=loop,
        **options
    ).load()
    return (game, clock, down, up)

def init_game(game, clock, down, up, loop=None):
    loop.create_task(clock(loop=loop))
    loop.create_task(game(loop=loop))

    progress = Persistent.recent_slot(game._services["progress.rson"].path)
    return (progress, down, up)

def create(parent, user, name, token, down=None, up=None, loop=None):
    return init_game(
        *create_game(parent, user, name, token, down, up, loop=loop),
        loop=loop
    )

Assembly.register(
    Clock.Tick, Game.Avatar, Game.Drama, Game.Item, Game.Tally, Game.Via,
    Model.Line, Player
)
コード例 #54
0
Alert = namedtuple("Alert", ["ts", "text"])
Scalar = namedtuple("Scalar", ["name", "unit", "value", "regex", "tip"])

Message = namedtuple("Message", ["header", "payload"])
Message.__doc__ = """`{}`

An Message object holds both protocol control information (PCI) and
application data.

    header
        PCI data necessary for the delivery of the message.
    payload
        Client data destined for the application endpoint.
""".format(Message.__doc__)

Assembly.register(Alert, Header, Message, Scalar)

def parcel(token, *args, dst=None, via=None, hMax=3):
    """
    :param token: A DIF token. Just now the function
                  `turberfield.ipc.fsdb.token`_ is the source of these.
    :param args: Application objects to send in the message.
    :param dst: An :py:class:`Address <turberfield.ipc.types.Address>` for the destination.
                If `None`, will be set to the source address (ie: a loopback message).
    :param via: An :py:class:`Address <turberfield.ipc.types.Address>` to
                pass the message on to. If `None`, the most direct route is selected.
    :param hMax: The maximum number of node hops permitted for this message.
    :rtype: Message


    """
コード例 #55
0
 def test_length_roundtrip(self):
     obj = Length.metre
     text = Assembly.dumps(obj)
     rv = Assembly.loads(text)
     self.assertEqual(obj, rv)
コード例 #56
0
ファイル: types.py プロジェクト: tundish/turberfield-ipc
# Turberfield 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 turberfield.  If not, see <http://www.gnu.org/licenses/>.

from collections import namedtuple

from turberfield.utils.assembly import Assembly

Address = namedtuple("Address",
                     ["namespace", "user", "service", "application"])
Address.__doc__ = """`{}`

A semantically hierarchical address for distributed networking.

    namespace
        Specifies the domain within which the address names are valid.
    user
        A unique name of trust within the network.
    service
        Identifies a currently operating instantiation of the network.
    application
        The name of the node endpoint.

""".format(Address.__doc__)

Assembly.register(Address)
コード例 #57
0
 def test_pellets_roundtrip(self):
     obj = Pellets.bag
     text = Assembly.dumps(obj)
     rv = Assembly.loads(text)
     self.assertEqual(obj, rv)