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)
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))
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)
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()) )
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)
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)
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)
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)
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)
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('"', "")))
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)")
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)
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)
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)
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
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))
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
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)
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))
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)
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
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)
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)
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)
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))
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))
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
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))
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")
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)
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
def test_shell_roundtrip(self): obj = Shell("pink") text = Assembly.dumps(obj) rv = Assembly.loads(text) self.assertEqual(obj, rv)
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, )
def setUpClass(cls): Assembly.register( Belt, Glyph, Length, Pellets, Shell, String, Wampum )
def test_string_roundtrip(self): obj = String(3) text = Assembly.dumps(obj) rv = Assembly.loads(text) self.assertEqual(obj, rv)
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)
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
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()))
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)
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)
# 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)
# 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)
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)
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()))
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)
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)
def test_glyph_roundtrip(self): obj = Glyph("eagle") text = Assembly.dumps(obj) rv = Assembly.loads(text) self.assertEqual(obj, rv)
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 )
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 """
def test_length_roundtrip(self): obj = Length.metre text = Assembly.dumps(obj) rv = Assembly.loads(text) self.assertEqual(obj, rv)
# 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)
def test_pellets_roundtrip(self): obj = Pellets.bag text = Assembly.dumps(obj) rv = Assembly.loads(text) self.assertEqual(obj, rv)