def describe_shrine(god, activity, data):
    ''' short description of a shrine for pins '''
    rules = {
        'start': 'A #descriptor# shrine to #god#.',
        'descriptor': '#adjective# #material#',
        'adjective': [
            'small', 'elaborate', 'popular', 'charming', 'sacred',
            'tucked-away', '' * 5],
        'god': [
            'the god #god_name#, who #appearance#',
            '#god_name#, a god who #appearance#',
        ],
        'appearance': 'is depicted as #depiction#',
        'god_name': get_latin(god['name'], capitalize=True),
        'depiction': god['description'],
        'material': [data['primary_material'], '' * 10],
        'sacrifice': 'Look for small sacrifices of #sacrifice_item# left ' \
                     'by believers.',
        'sacrifice_item': [
            'blood', 'hair', 'teeth', 'fresh fruit' * 5, 'secrets',
            'loose change', 'bread', 'handmade icons' * 3],
        'omens': 'You may find a believer casting their fortune with '\
                 '#omen_object#.',
        'omen_object': [
            'polished stones', 'divining cards', 'lots', 'finger bones',
            'animal bones', 'stones', 'ceramic tiles', 'marble tiles',
            'carved sticks'],
    }
    if activity in ['sacrifice', 'omens']:
        rules['start'] += ' #%s#' % activity
    grammar = tracery.Grammar(rules)
    return format_text(grammar.flatten('#start#'))
def local_dish(data):
    ''' a stew made from blip and blap '''
    rules = {
        'start': '#type# made with #main_ingredient# and #ingredient#',
        'type': [
            '#soup_adjective# soup',
            'dish',
            'stir-fry',
            'pie',
            'stew',
            'spread',
            'flatbread',
            'dumpling',
            'wrap',
        ],
        'soup_adjective': [
            'thick', 'thin', 'clear', 'hot', 'creamy',
            'rich', 'light'],
        'main_ingredient': ['#meat#', '#vegetable#'],
        'ingredient': ['a vegetable called #vegetable2#'],
        'meat': ['%s meat' % get_latin(a['name']) \
                 for a in data['cuisine']['animals']] + \
                ['pork', 'beef', 'lamb', 'chicken', 'game', 'fish'],
        'vegetable': '<em>%s</em>' % \
                get_latin(data['cuisine']['vegetables'][0]['name']),
        'vegetable2': '<em>%s</em>' % \
                get_latin(data['cuisine']['vegetables'][1]['name']),
    }

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')
    return format_text(sentence)
def describe_specialty(name, product, data):
    ''' the city is famous for .... bread? '''
    rules = {
        'start': [
            '#city# is #famous# for its #product#, and #superlative#.',
            '#product# is big business in #city#, and #superlative#.',
            '#city#\'s name is practically synonymous with #product#, ' \
                'and #superlative#.',
        ],
        'product': product,
        'name': get_latin(name, capitalize=True),
        'city': get_latin(data['city_name'], capitalize=True),
        'famous': [
            'famous', 'world renowned', 'renowned', 'known',
            'known far and wide',
        ],
        'superlative': [
            'this is the #best# destination to partake',
            'there\'s no better introduction to the local specialty than ' \
                '#name#',
            'it doesn\'t get better than #name#',
            '#name# is the best in the business',
        ],
        'best': ['best', 'number one'],
    }

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
def tea(climate):
    ''' describe a cup of tea '''
    rules = {
        'start': [
            'is served #temperature#. ' \
            'It is steeped to #milk_part#, and #tea_flavor#. ' \
            'People sometimes drink it with #additive#, ' \
            'and it is thought to have a mild #drug# effect.' \
        ],
        'temperature': ['scalding hot and #too_hot#',
                        'steaming hot, #container#',
                        'warm, #container#'],
        'too_hot': [
            'has to be drunk in small, slurping sips that ' \
                    'aerate and cool it down',
            'is sipped from a shallow spoon to avoid burning oneself',
            'the fragrant steam is enjoyed as a first course ' \
                    'while the tea cools',
            'is poured between a set of small cups to cool it'
        ],
        'container': [
            'ladled out of a large pot',
            'from large kettle',
            'the leaves brewed in the cup',
            'brewed from a spoonful of ground powder whisked with water ' \
                    ' in the cup'
        ],
        'tea_flavor': 'has a flavor reminiscent of #sweet# ' \
                'and #savory#',
        'sweet': ['honey', 'cardamom', 'cinnamon', 'cloves', 'chocolate',
                  'anise', 'mint', 'chocolate', 'vanilla'],
        'savory': ['pepper', 'chili', 'tarragon', 'basil', 'sage', 'vervain'
                   'grass', 'lemongrass', 'cumin'],
        'milk_part': ['a #tea_color# color, opaque from added #milk#'] + \
                      ['a #tea_color# color'] * 5,
        'tea_color': ['red-brown', 'yellow-green',
                      'golden yellow', 'dark green', 'grassy',
                      'orange-red', 'reddish'],
        'milk': ['milk', 'nut milk'],
        'additive': ['a sweet fruit syrup', 'a little salt', 'honey',
                     'a sour citrus juice a bit like lime',
                     'a pinch of dried, ground bark' \
                    ],
        'drug': ['stimulant', 'soporific', 'dizzying', 'hallucinatory',
                 'dissociative', 'calming', 'pain-relieving'],
    }

    if 'arctic' in climate or 'polar' in climate:
        rules['too_hot'].append(
            'a ceramic jar of flaked ice is brought out alongside it,' \
            'to dilute and cool the drink as desired')
        rules['milk'].append('butter')

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
def teacup(material, motif):
    ''' describe the cup tea is drunk from '''
    dishware = {
        'wood': '#shape_part# wooden cups, ' \
                'lacquered and painted with #motif#',
        'stone': '#shape_part# stone cups with ' \
                '#motif# caved along the rim',
        'cloth': '#shape_part# ceramic cups glazed with #motif#',
        'brick': '#shape_part# ceramic cups glazed with #motif#',
        'straw': '#shape_part# ceramic cups glazed with #motif#',
        'glass': '#shape_part# glass cups painted with #motif#',
        'metal': '#shape_part# metal cups embossed with #motif#',
        'tile': '#shape_part# ceramic cups glazed with #motif#',
    }
    pattern = {
        'circles': [
            'a series of evenly spaced dots',
            'overlapping circles of various sizes',
            'partial circles like waxing and waning phases of the moon',
            'concentric circles',
            'spiraling lines',
        ],
        'patterning': [
            'an intricate lace-like pattern',
            'intersecting geometric lines',
        ],
        'triangles': ['a ring of triangles', 'chevron lines'],
        'squares': [
            'squares',
            'a pattern of diamond shapes',
            'a grid of lines',
        ],
        'representation': [
            'the outline of plants and vines',
            'small, ground-dwelling animals',
            'a pattern of flowers',
            'leaves and branches',
            'a design of beetle carapaces',
            'birds in flight',
            'dancing figures',
        ]
    }
    rules = {
        'start': '#material#',
        'shape_part': '#shape#',
        'shape': ['tall', 'shallow', 'round', 'narrow', 'fluted'],
        'material': dishware[material],
        'motif': pattern[motif],
    }
    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
Beispiel #6
0
def slogan(data):
    ''' describe the cup tea is drunk from '''
    options = [
        urban_garden,
        wow_old,
        beacon_of,
        beacon_of,
        regional_gem,
        regional_gem,
        activity,
        activity,
        activity,
    ]
    return format_text(random.choice(options)(data))
def describe_temple(god, activity, data):
    ''' longer description of a temple and religious activity '''
    materials = {
        'brick': ['clay', 'ceramic'],
        'straw': ['woven straw', 'woven'],
        'wood': ['wooden', 'carved wood'],
        'stone': ['carved stone', 'stone', 'marble', 'stone inlayed'],
        'cloth': ['woven', 'tapestry'],
        'glass': ['blown glass', 'glass', 'stained glass'],
        'metal': ['hammered metal', 'metal', 'metal inlayed'],
        'tile': ['mosaic', 'tile mosaic'],
        'concrete': ['cement', 'brutalist', 'molded concrete'],
    }
    rules = {
        'start': [
            'This temple, devoted to #god#, is famous for its artfully ' \
                'crafted #material# icons and decorations.',
            'Believers gather at this temple #activity#.',
        ],
        'god': [
            'the god #god_name#, who #appearance#',
            '#god_name#, a god who #appearance#',
        ],
        'appearance': 'is depicted as #depiction#',
        'activity': '#%s#' % activity,
        'prayer': 'to pray to #god# for good fortune and health',
        'oracle': 'to consult the oracle, who sits on a #secondary_material# '\
                  'dais and dispenses advice and wisdom',
        'posession': 'for a ceremony in which #god_name#, who is believed to '\
                     'take the form of #depiction#, posesses a true believer '\
                     'and acts through their body, causing them to #movement#.',
        'glossolalia': 'for a ritual in which believers channel the word of '\
                       '#god#, and chant in a mysterious divine language.',
        'sacrifice': '#prayer#',
        'omen': '#prayer#',
        'visions': '#prayer#',
        'movement': [
            'dance', 'spasm', 'leap and cavort', 'sway and sing',
            'contort into unnatural positions'],
        'god_name': get_latin(god['name'], capitalize=True),
        'depiction': god['description'],
        'material': materials[data['primary_material']] +
                    materials[data['secondary_material']],
    }
    grammar = tracery.Grammar(rules)
    return format_text(grammar.flatten('#start#'))
def vegetable():
    ''' brief description of a vegetables '''
    rules = {
        'start': 'a #type#, with #texture#, '\
                 '#color_part# flesh',
        'type': ['squash', 'tuber', 'root vegetable', 'brassica',
                 'leafy green', 'vegetable stalk', 'legume'],
        'color_part': ['#color#', 'pale #color#', 'deep #color#',
                       'mottled #color#-on-#color#',
                       'spotted #color#-on-#color#',
                       'speckled #color#-on-#color#'],
        'color': ['red', 'orange', 'yellow', 'green', 'purple', 'white'],
        'texture': ['firm', 'stringy', 'soft', 'sticky', 'spongy']
    }

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')
    return format_text(sentence)
def describe_gods(gods, data):
    ''' basic description of the deity '''

    rules = {
        'start': '#single#' \
            if data['deity_form_secondary'] == 'none' \
            else '#dual#',
        'single': 'a #primary_form#',
        'dual': [
            'a hybrid #primary_form# and #secondary_form#',
            'a #primary_form# with a #secondary_form#\'s head',
            'half #primary_form# and half #secondary_form#',
        ],
        'primary_form': '#%s#' % data['deity_form'],
        'secondary_form': '#%s#' % data['deity_form_secondary'],
        'animal': [
            'serpent', 'bird', 'fish', 'lizard', 'deer', 'rat', 'dog',
            'rabbit', 'rodent', 'beetle', 'spider', 'snake', 'cat'],
        'plant': [
            'tree', 'tangle of vines', 'flower', 'seed pod', 'thick foliage',
            'tuft of grass'],
        'element': [
            'flame', 'ball of fire', 'boulder', 'gust of wind',
            'winding river', 'rain', 'cloud', 'plume of smoke',
            'pillar of stone', 'pillar of packed earth', 'slab of stone',
            'waterfall'],
        'human': '#descriptor# #person#',
        'descriptor': [
            'ancient', 'beautiful', 'hideous', 'wizended',
            'elderly', 'young', 'handsome', 'gigantic', 'diminutive', 'rotund',
            'athletic'],
        'person': ['person', 'human', 'child'],
    }
    if len(data['genders']) == 2:
        rules['person'] += ['man', 'woman']

    grammar = tracery.Grammar(rules)
    for god in gods:
        description = grammar.flatten('#start#')
        god['description'] = format_text(description)

    return gods
def fruit(climate):
    ''' describe a so called .... "fruit" '''

    # BERRIES FOR ALL
    fruits = ['#berry#']
    if 'tropical' in climate:
        # tropical climates can have citrus, but it stays green.
        # I'm skipping it here just for local variation
        fruits += ['#melon#', '#fruit_detail#']
    elif climate in ['hot desert', 'arid', 'steppe']:
        fruits += ['#fruit_detail#']
    elif 'polar' not in climate and 'arctic' not in climate:
        fruits += ['#citrus#', '#fruit_detail#']


    rules = {
        'start': 'a #shape# #fruit# #eating_part#',
        'fruit': fruits,
        'fruit_detail': '#pit#. #outside_part#. ' \
                 + 'The flesh is #inside#, #inside_part#.',
        'berry': 'berry, #color_part# with a #flavor_part# taste and ' \
                 + '#juice_part#.',
        'citrus': 'citrus fruit with #color_part# peel and spongy pith. ' \
                  + 'The flesh is #inside_part#.',
        'melon': 'melon with #color_part# rind '  \
                 'and #flavor_part# flesh, #color_part# in color, ' \
                 + 'with #juice_part#.',

        'color_part': ['#color#', 'light #color#', 'dark #color#',
                       'muted #color#', 'vibrant #color#',
                       'mottled #color#-on-#color#',
                       'spotted #color#-on-#color#',
                       'speckled #color#-on-#color#'],
        'color': ['red', 'orange', 'yellow', 'green'],

        'shape': ['round', 'knobby', 'oblong', 'star-shaped', 'hand-shaped',
                  'spiky', 'teardrop-shaped', 'bulbous',
                  'round', 'oval'],
        'pit': ['stone fruit with a #size# pit',
                'fruit with #size#, crunchy seeds',
                'fruit with a fibrous core containing #size# seeds',
                'fruit with #size# seeds'],
        'size': ['large', 'small'],

        'flavor_part': '#flavor_modifier# #flavor#',
        'flavor_modifier': ['mildly', 'intensely', 'lightly'],
        'flavor': ['sweet', 'sweet', 'sweet',
                   'astringent', 'sour', 'bitter'],

        'juice_part': '#juice# juice',
        'juice': ['milky', 'viscous', 'thin', 'sticky', 'fragrant',
                  'syrupy'],

        'outside_part': ['#outside_inedible#',
                         '#outside_edible#',
                         '#outside_edible#'],
        'outside_inedible': [
            'It has a hard, #color_part# shell ' \
            + 'that cracks open in your hand',
            'The #outside# is #color_part# and inedible'],
        'outside_edible': 'The #outside# is #color_part# and ' \
                           + 'has a #flavor_part# flavor',
        'outside': ['peel', 'rind'],

        'inside_part': '#color_part# and #flavor_part#, with #juice_part#',
        'inside': ['segmented', 'goopy', 'stringy', 'soft'],

        'eating_part': ['It is eaten #eating#. ', '', '', '', ''],
        'eating': [
            '#eating_method_raw# or #eating_method_cooked#',
            '#eating_method_raw#',
            '#eating_method_raw#',
            '#eating_method_raw#',
            '#eating_method_raw#',
            '#eating_method_cooked#'],
        'eating_method_raw': [
            'raw', 'peeled and sliced', 'with a spoon',
            'mashed into a paste'],
        'eating_method_cooked': [
            'grilled', 'as preserves',
            'dried', 'as a jam', 'boiled', 'blanched',
            'with salt', 'cooked with herbs'],
    }

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
    async def send_trade(self, trade):
        if self.double_check:
            print_timestamp(
                f"Double-checking new {self.trade_type} trade: {trade['id']}")
            await asyncio.sleep(10)
            while True:
                try:
                    trades_info = await self.user.get_trade_status_info(
                        tradeStatusType=self.trade_type)
                    break
                except (httpx.ConnectTimeout, httpx.ReadTimeout,
                        httpx.ConnectError):
                    logging.error(
                        f"Connect/Read timed out while trying to grab trade status info for double-check: {self.trade_type}: {traceback.format_exc()}"
                    )
                    print_timestamp(
                        f"Connect/Read timed out while trying to grab trade status info for double-check: {self.trade_type}"
                    )
                    await asyncio.sleep(5)
            if trade['id'] not in [
                    trade['id'] for trade in trades_info['data'][::-1]
            ]:
                print_timestamp(
                    f"New {self.trade_type} trade {trade['id']} detected as fake."
                )
                return

        try:
            self.roli_data = await get_roli_data()
        except httpx.ReadTimeout:
            logging.error(
                f"Couldn't grab Rolimons data. Read timed out: {traceback.format_exc()}"
            )
            print_timestamp(
                f"Couldn't grab updated Rolimons data. Read timed out.")
        except Exception:
            logger.critical(
                f"Unknown error while grabbing rolimons data: {traceback.format_exc()}\nRolimons data is now: {self.roli_data}"
            )

        trade_info = await self.user.get_trade_info(trade['id'])
        trade_data = construct_trade_data(trade_info, self.roli_data,
                                          self.user.id,
                                          self.add_unvalued_to_value,
                                          self.trade_type)

        asset_ids = []
        for offer in (trade_data['give'], trade_data['take']):
            for item in offer['items'].values():
                if str(item['assetId']) not in asset_ids:
                    asset_ids.append(str(item['assetId']))

        asset_images = {}
        asset_image_urls = await get_asset_image_url(asset_ids=asset_ids,
                                                     size="700x700")
        for item in asset_image_urls["data"]:
            asset_images[str(
                item["targetId"])] = await get_pillow_object_from_url(
                    item["imageUrl"])
        for offer in (trade_data['give'], trade_data['take']):
            for item in offer['items'].values():
                item['pillowImage'] = asset_images[str(item['assetId'])]

        try:
            themes_folder = os.path.join(self.main_folder_path, "themes")
            theme_folder = os.path.join(themes_folder, self.theme_name)
            builder = NotificationBuilder(theme_folder)
            image_bytes = builder.build_image(trade_data)
        except Exception:
            logging.error(
                f"An unknown error occurred while creating a notification image: {traceback.format_exc()}"
            )
            print_timestamp(
                f"An unknown error occurred while creating a notification image: {traceback.format_exc()}"
            )

        content = format_text(self.webhook_content, trade_data)

        try:
            await send_trade_webhook(self.webhook_url,
                                     content=content,
                                     attachments=[("trade.png", image_bytes)])
            logging.info(
                f"Sent {self.trade_type} trade webhook: {trade['id']}")
            print_timestamp(
                f"Sent {self.trade_type} trade webhook: {trade['id']}")

        except UnknownResponse:
            logging.error(
                f"Unable to send {self.trade_type} trade webhook: {trade['id']} {traceback.format_exc()}"
            )
            print_timestamp(
                f"Unable to send {self.trade_type} trade webhook: {trade['id']}"
            )
    def build_image(self, trade_data: dict):
        """Takes in trade data and builds notification according to theme_setup, in the order that it's written in theme_setup.
        """
        notification = self.load_image(
            os.path.join(self.theme_folder, self.settings['background_image']))
        for section, details in self.settings.items():
            if section == "background_image":
                continue

            elif section in ("give", "take", "drawn_images"):
                for item_name, item_details in details.items():
                    background = notification

                    if section == "drawn_images":
                        foreground = self.load_image(
                            os.path.join(self.theme_folder,
                                         item_details['file_name']))
                    else:
                        try:
                            foreground = trade_data[section]['items'][
                                item_name]['pillowImage']
                        except KeyError:  # Catching keyerror for trades that have less than 4 items on a side
                            continue

                    foreground = self.resize_image(foreground,
                                                   tuple(item_details['size']))

                    position = item_details['position']

                    if item_details['center_on_position']:
                        position[0] = int(
                            round(position[0] - (item_details['size'][0] / 2)))
                        position[1] = int(
                            round(position[1] - (item_details['size'][1] / 2)))
                    position = tuple(position)

                    transparency = item_details['transparency']

                    self.stitch_images(background,
                                       foreground,
                                       position,
                                       transparency=transparency)
                    continue

            elif section == "drawn_text":
                for text_details in details.values():
                    background = notification
                    position = tuple(text_details['position'])
                    text = format_text(text_details['text'],
                                       trade_data=trade_data)
                    rgba = tuple(text_details['rgba'])
                    font = self.load_font(os.path.join(
                        self.theme_folder, text_details['font_file']),
                                          font_size=text_details['font_size'])

                    anchor = "la"
                    if text_details['center_on_position']:
                        anchor = "mm"

                    stroke_rgba = tuple(text_details['stroke_rgba'])
                    stroke_width = text_details['stroke_width']

                    background = self.stitch_text(background,
                                                  position,
                                                  text,
                                                  rgba=rgba,
                                                  font=font,
                                                  anchor=anchor,
                                                  stroke_rgba=stroke_rgba,
                                                  stroke_width=stroke_width)
                    continue

            else:
                print(f"Unknown theme section: {section}")
                continue

        notification_bytes = BytesIO()
        notification.save(notification_bytes, "PNG")
        notification_bytes.seek(0)

        return notification_bytes
def eatery(name, dish, category, data):
    ''' a charming stone hut where they serve tea '''
    earliest = data['founded'] if data['founded'] > 1700 else 1700
    founding = random.randint(earliest - 4, datetime.now().year - 4)

    materials = {
        'brick': ['pottery', 'ceramic'],
        'straw': ['woven straw', 'straw'],
        'wood': ['wood'],
        'stone': ['marble', 'stonework'],
        'cloth': ['textile', 'tapestry'],
        'glass': ['glass', 'stained glass'],
        'metal': ['metal'],
        'tile': ['mosaic', 'tile'],
    }
    rules = {
        # structures
        'start': [
            '''With a gourmet, #cuisine# menu and #vibe_part#, #name# is a
               #platitude#. It will have you craving perennial favorites
               like #dish#. The setting, in a #space#, is stunning, a perfect
               #city# experience.''',
            '''Owner #chef# has given #cuisine# cuisine a modern edge while
               still staying true to the regional style. The venue is stunning,
               a #space# and #vibe_part#. Be sure to try the #dish#.''',
            '''In this #vibe# #type#, you can settle down in a #space#. The menu
               features staples of #cuisine# cuisine, and is best known for
               traditional-style #dish#.''',
            '''#name# is a #cuisine# restaurant in #city# that's been
               going strong since #founding#. With a #vibe_part# and attentive
               service, it offers #cuisine# cuisine in a #space#.''',
            '''#name# is a #vibe# #type# in a welcoming environment. It offers
               excellent #cuisine# food. The #dish# is hard to beat.''',
            '''This #space# gets rave reviews for
               #positive# and affordable #cuisine# food and ambiance. The
               #vibe_part# makes it a #platitude#.''',
            '''#name# is one of #city#'s best #cuisine# restaurants. It's a
               #platitude# where you can enjoy this #space#. There are a
               #positive# range of dishes on offer, including #dish#.''',
            '''This #platitude# opened in #founding# and has set the tone for
               #city# cuisine ever since. Regulars like to order #dish#, sit
               back, and enjoy the #vibe_part#.''',
            '''Something of a social hub in #city#, this #vibe# #type#
               doesn't exactly advertise itself, but the #dish# is #positive#.
               Overall a #platitude#.''',
            '''A popular #vibe# cafe in the heart of #city# serving
               #dish# and drinks.''',
            '''Founded in early #founding#, #name# serves arguably the best
               know #dish# in town and it deserves that distinction. It has a
               #secondary_material_fancy#-decked interior and a #vibe_part#.''',
            '''This simple place, popular with the city workers, covers the
               bases for a #positive# lunch of #dish#.''',
            '''#name# is a rather dark and seedy place to say the least, but
               within its #material# walls you'll get a #positive# range of
               local dishes.''',
            '''This simple seven-table place offers #positive# breakfasts and
               gets packed by lunchtime -- and rightly so. The #dish# is a
               killer (not literally!).''',
        ],

        # info
        'name':
        '<em>%s</em>' % name,
        'type':
        category,
        'city':
        '<em>%s</em>' % get_latin(data['city_name'], capitalize=True),
        'neighborhood':
        'the <em>%s</em> district' %
        get_latin(random.choice(data['geography']['neighborhoods']),
                  capitalize=True),
        'founding':
        str(founding),
        'chef':
        data['get_person']('chef')['name'],

        # descriptive componenets
        'cuisine':
        '<em>%s</em>ian-style' % get_latin(data['country'], capitalize=True),
        'dish':
        '"<em>%s</em>" (a %s)' %
        (get_latin(dish['name']), dish['description']),
        'platitude': [
            'enduring favorite',
            'first-rate establishment',
            'local go-to',
            'local favorite',
            'popular place',
            'much loved #type#',
            'prestigious',
            'foodie oasis',
        ],
        'vibe_part':
        '#vibe# #atmosphere#',
        'space': [
            '#stories# with #color#-painted #material# walls and #accent#',
            'stylish #material# and #secondary_material# #stories#',
        ],
        'stories':
        '#%s#' % data['stories'],
        'single': ['building', '#type#'],
        'multi':
        'spacious #building#',
        'many':
        '%s-floor #building#' %
        random.choice(['first', 'second', 'third', 'fourth', 'fifth', 'top']),
        'accent':
        '#secondary_material# #accent_object#',
        'accent_object': ['wall-hangings', 'doorways', 'lamps'],
        'material':
        data['primary_material'],
        'secondary_material':
        data['secondary_material'],
        'secondary_material_fancy':
        materials[data['secondary_material']],
        'building': ['suite', 'hall', 'room', '#type#'],

        # wordlists
        'atmosphere': ['atmosphere', 'charm'],
        'positive': [
            'top notch', 'good', 'great', 'fantastic', 'excellent',
            'high caliber', 'wonderful', 'abundant'
        ],
        'vibe': [
            'bustling',
            'busy',
            'relaxing',
            'sophisticated',
            'quaint',
            'cozy',
            'elegant',
            'world-renowned',
            'laid-back',
        ],
        'color':
        ['red', 'orange', 'yellow', 'green', 'purple', 'white', 'pink'],
    }
    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
Beispiel #14
0
def animal(climate, terrain):
    ''' urban wildlife '''
    rules = {
        'start': '#type#. #human_interaction#.',
        'type': [
            '#bird#', '#rodent#', '#raccoon#', '#coyote#'
        ],
        'insect': 'insects that #behavior#',
        'bird': '#size#, #color# #bird_type# with #bird_accent# ' \
                'that #bird_behavior#',
        'rodent': '#size# #warm_color# rodents that #behavior#',
        'raccoon': '#size#, raccoon-like animals that #behavior#',
        'coyote': '#size# wild dogs with #warm_color# and #color# coats. '\
                  'It is said that they #behavior#',

        # birds
        'bird_type': ['raptors'] + 10 * ['songbirds', 'birds'],
        'bird_accent': [
            'dark #color# wings',
            '#warm_color# throats',
            '#cold_color# bellies',
            '#cold_color# tails',
            '#color# heads',
            'striking #warm_color# beaks',
            'sharp talons',
            'long, flowing tails',
            'crooked beaks'
        ],

        'size': ['large', 'small', 'tiny'],
        'color': ['white', 'brown'],
        'warm_color': ['red', 'pink', 'orange', 'yellow'],
        'cold_color': ['green', 'blue', 'teal', 'purple'],

        'behavior': [ # behavior that can apply to various types of critter
            'build nests out of #weird_material#',
            'make jewelry-like adornments for themselves from plants',
            'wear hats made from cup-shaped leaves or blossoms',
            'collect #weird_material# and offers its collection to' \
                    'potential mates',

            'mate for life, and remain alone if their mate dies',
            '#cry_verb# human laughter',
            '#cry_verb# an infant\'s scream',
            '#cry_verb# clanking metal',
            '#cry_verb# grinding stones',
            '#cry_verb# dripping water',
            '#cry_verb# a scream of fear',
            '#cry_verb# a wolf howl',
            '#cry_verb# a lion\'s roar',

            'can run as fast as 30 miles per hour',
            'can eat plastic',
            'eat clay to aid their digestion',
            'perform elaborate dances to attract a mate',
            'can turn their heads almost all the way around',
            'howl at the moon',
            'hunt by smell',
            'are totally blind, and navigate by sound',
            'have to eat their bodyweight in food each day',
            'can catch and spread human diseases',
            'run faster than horses',
            'are born a downy coat that they later shed',
            'have digestive systems that can filter out toxins and poisons',
            'rely on one variety of rare, native grass as a dietary staple',
            'have perfectly #cold_color# eyes',
            'have different colored eyes',
            'vastly outnumber humans',
            'have #cold_color#ish #warm_color# blood',
            'scavenge scraps of cloth to swaddle their young',
            'kidnap and raise other animal\'s young as their own',
            'have complex family and social relationships',
            'give each other gifts of particularly beautiful stones',
            'have names for each other',
            'are fastidiously tidy',
            'eat their mates',
            'are consumed by their own offspring',
            'can change gender at will',
            'can reproduce asexually if they are unable to find a mate',
            'can go %d weeks without eating' % random.randint(2, 5),
            'can solve complex puzzles and open doors',
            'live up to %d years of age' % random.randint(20, 200),
            'prefer to take over human structure\'s for nests',
            'build huts for themselves out of woven branches',
            'taste with their feet',
            'have regional dialects and accents',
            'can drink near-freezing or boiling water',
            'can sever a person\'s head from their body in one stroke',
            'befriend spiders',
            'can kill with one venemous bite',
            'can jump as high as 30 feet',
            'sleep for as much as 18 hours a day',
            'groom each other to show affection',
            'dye patches of their back with #cold_color# sap',
        ],
        'weird_material': [
            'human skin',
            'scavenged bones',
            'scavenged teeth',
            'stolen articles of clothing',
            'flower petals',
            'sap extracted from trees and hardened into a strong resin',
            'wires stolen from electronics',
            'pages of books',
            'human hair',
            'stolen shoes',
            'bright-colored threads and scraps of fabric',
            'fruit skins',
            'globules of their saliva',
        ],
        'cry_verb': [
            'emit cry that sounds like',
            'have a call that sounds like',
            'make a sound like',
        ],

        'human_interaction': [
            'Locals believe #belief#',
            'Local children like to catch them and keep them as pets',
            'They are hunted for food, and considered a delicacy',
            'They are considered a pest',
            'Locals do not acknowledge their presence',
        ],
        'belief': [
            'they are manifestations of the spirits of the dead',
            'they can travel into the afterlife',
            'they know how you will die',
            'they know your secrets',
            'they have secret names',
            'they steal memories, causing forgetfulness',
            'they feed on human sadness',
            'they can communicate with infants',
            'they can speak to the dead',
            'they are representatives of the divine',
            'they can speak with humans if they choose to',
            'they bring good luck',
            'they bring bad luck',
            'they are harbingers of birth',
            'they are harbingers of death',
            'they are harbingers of change',
            'they watch our dreams as we sleep',
            'they steal children who wander too far from their homes',
            'they protect infants from sickness and ill fortune',
            'they can transform into humans under certain conditions',
            'they can return from death',
            'their bones have healing properties',
            'they can predict the weather',
            'they can read and understand human language',
            'it is bad luck to hurt them',
            'they hold wild bacchanalias in the dead of night',
            'they imitate voices of loved ones to lure people into traps',
        ],
    }

    # added after so that the odds aren't skewed
    rules['bird_behavior'] = rules['behavior'] + [
        'can mimick human speach'
        'mimicks ambient noises and speach',
        '#cry_verb# ocean waves',
        '#cry_verb# radio static',
        '#cry_verb# gusts of wind',
        '#cry_verb# bits of music',
        '#cry_verb# running water',
        '#cry_verb# rainfall',
        'can fly for days without rest',
    ]

    if terrain == 'coast':
        rules['bird_type'] += ['sea birds', 'aquatic birds']
        rules['color'] += ['gray', 'pale blue']

    if 'tropical' in climate:
        rules['color'] += [
            'brightly colored', 'multicolored', '#warm_color#',
            'bright #warm_color# and #cold_color#', '#cold_color#'
        ]
        rules['type'].append('#insect#')
    elif climate in ['arid', 'semi_arid', 'hot_desert']:
        rules['color'] += [
            'dusty #warm_color#', 'muted #warm_color#', '#warm_color#'
        ]
    else:
        rules['color'] += ['#warm_color#', '#cold_color#']

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)
def body_mod(genders, motif):
    ''' describe a body modification '''
    pattern = {
        'circles': [
            'black bands of ink',
            'circles of interlocking lines and shapes',
            'chain-like patterns of broken rings',
            'a pattern like the splash of raindrops in a puddle',
            'radiating symmetrical designs like the tiles on Mosques',
            'concentric circles like staring eyes',
        ],
        'patterning': [
            'patterns almost like the trumps in a deck of playing cards',
            'precise, fine-lined patterns like expensive lace',
            'curving blocks of color',
            'abstract flourishes like you might find on a title page',
        ],
        'triangles':
        ['bands of equilateral triangles', 'neat chevron lines of black ink'],
        'squares': [
            'a grid of small, carefully drawn squares',
            'a row of rectangles symbolizing various life events',
            'diamond shaped blocks of black ink',
            'straight, dark lines, at odds with the curve of the body',
        ],
        'representation': [
            'depictions of leaves and flowers',
            'tangled vines as if the body was the trunk of an old tree',
            'shadows of animals',
            'blocks of text that tell strange and obscure stories',
        ]
    }
    rules = {
        'start': '#genders# #type# and #hair_mod#.',
        'genders': [random.choice(['women', 'men']) * 5 if genders == 2 else 'people',
            'children', 'adolescents', 'adults', 'locals'],
        'type': [
            'pierce their #pierce_spot# with #jewelry#',
            'tattoo their #tattoo_spot# with #motif#',
            '#hair_removal# their #hair_spot# bald'],
        'pierce_spot': ['lips', 'ears', 'noses', 'cheeks'],
        'tattoo_spot': [
            'hands', 'arms', 'faces', 'necks', 'bodies', 'palms',
            'chests', 'backs', 'torsos'],
        'motif': pattern[motif],
        'jewelry': [
            '#material# bangles', 'polished #material# spikes',
            'jewelry carved from #carvable_material#',
            'finely crafted #material# jewelry'],
        'hair_removal': ['pluck', 'shave'],
        'hair_spot': ['eyebrows', 'temples', 'faces'],
        'hair_mod': [
            'dye their hair #colors#, wearing it #hair_style#',
            'wear their hair cut short, #hair_style#',
            'sheer the hair to the scalp on parts of their head and ' \
                    'leave the rest long, #hair_style#',
            'indicate their social rank and status by the length of ' \
                    'their hair, #hair_style#',
            'braid their hair, #hair_style#'],
        'hair_style': [
            'pulled back with carved #carvable_material# combs',
            'letting it hang straight and loose',
            'slicked down against the scalp',
            'kept in place with colored ribbons',
            'worn short and bristling',
            'the wiry curls quite voluminous',
        ],
        'colors': ['black', 'unnatural colors', 'white', 'dark red'],
        'material': [
            'stone', 'obsidian', 'crystal',
            'bone', 'ivory',
            'wood',
            'brass', 'gold', 'silver', 'copper', 'metal',
            'glass', 'clay', 'ceramic',
        ],
        'carvable_material': [
            'obsidian', 'crystal',
            'bone', 'ivory',
            'wood' * 5,
        ],
    }

    grammar = tracery.Grammar(rules)
    sentence = grammar.flatten('#start#')

    return format_text(sentence)