drakosfire commited on
Commit
c8a4cd8
1 Parent(s): 760ff9a

Committing to prep to branch for new custom UI build

Browse files
Files changed (4) hide show
  1. app.py +119 -25
  2. process_html.py +407 -294
  3. process_text.py +160 -14
  4. utilities.py +0 -3
app.py CHANGED
@@ -5,6 +5,7 @@ import os
5
  import ctypes
6
  import store_helper as sh
7
  import process_text
 
8
 
9
 
10
  # This is a fix for the way that python doesn't release system memory back to the OS and it was leading to locking up the system
@@ -15,19 +16,20 @@ M_MMAP_THRESHOLD = -3
15
  libc.mallopt(M_MMAP_THRESHOLD, 2**20)
16
 
17
  # Declare accessible directories
18
- base_dir = os.path.dirname(os.path.abspath(__file__)) # Gets the directory where the script is located
19
  print(f"Base Directory :",base_dir)
20
  list_of_static_dir = [os.path.join(base_dir, "output"),
21
  os.path.join(base_dir, "dependencies"),
22
  os.path.join(base_dir, "galleries")]
23
  gr.set_static_paths(paths=list_of_static_dir)
24
 
 
25
  # Build gradio app
26
  # Storing everything inside the Blocks to be accessible to the app
27
 
28
  with gr.Blocks() as demo:
29
  # Functions and State Variables
30
- store= gr.State()
31
  store_name = gr.State()
32
  store_description = gr.State()
33
  store_reputation = gr.State()
@@ -44,9 +46,9 @@ with gr.Blocks() as demo:
44
  notable_customers = gr.State()
45
  store_quests = gr.State()
46
  store_rumors = gr.State()
 
47
  store_inventory = gr.State()
48
  store_inventory_dict = gr.State()
49
-
50
  specialties_description = gr.State()
51
 
52
  def check_and_process_contents(item):
@@ -64,25 +66,27 @@ with gr.Blocks() as demo:
64
  # Key List for checking is speciufic keys are present before running parsing functions
65
  keys_list = list(llm_output)
66
  store_name_value = store_dict['store_name']
67
- store_description_value = store_dict['description']
68
- store_reputation_value = store_dict['reputation']
69
- store_backstory_value = store_dict['backstory']
70
  store_sd_prompt_value = store_dict['store_sd_prompt']
71
- store_type_value = store_dict['type']
72
- store_size_value = store_dict['size']
73
- store_location_value = check_and_process_contents(store_dict['location'])
74
- store_owner_value = check_and_process_contents(store_dict['owners'])
75
- store_employees_value = check_and_process_contents(store_dict['employees'])
76
  store_hours_value = store_dict['store_hours']
77
- store_services_value = check_and_process_contents(store_dict['services'])
78
- store_specialties_value = check_and_process_contents(store_dict['specialties'])
79
- notable_customers_value = check_and_process_contents(store_dict['notable_customers'])
80
- store_quests_value = check_and_process_contents(store_dict['related_quests'])
81
- store_rumors_value = check_and_process_contents(store_dict['rumors'])
 
82
 
83
 
84
  #Return each State variable twice, once to the variable and once to the textbox
85
- return [store_name_value, store_name_value,
 
86
  store_description_value, store_description_value,
87
  store_reputation_value, store_reputation_value,
88
  store_backstory_value, store_backstory_value,
@@ -97,26 +101,84 @@ with gr.Blocks() as demo:
97
  store_services_value, store_services_value,
98
  store_specialties_value, store_specialties_value,
99
  store_quests_value, store_quests_value,
100
- store_rumors_value, store_rumors_value
 
101
  ]
102
 
103
  def gen_store_inventory(store_name, store_type, store_size, store_owner, store_reputation):
104
  inventory_description = f"{store_name}, {store_type} {store_size} {store_owner} {store_reputation}"
105
  inventory_dict = sh.call_llm_and_cleanup(inventory_description, inventory=True)
106
  inventory_dict = sh.convert_to_dict(inventory_dict)
107
- if inventory_dict['inventory']:
108
- store_inventory_value = inventory_dict['inventory']
109
  store_inventory_value = process_text.format_inventory(store_inventory_value)
110
 
111
  #Return each State variable twice, once to the variable and once to the textbox
112
  return [store_inventory_value,store_inventory_value
113
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  def inventory_to_dict(inventory):
116
- inventory_dict = process_text.parse_text_to_inventory(inventory)
 
117
  inventory_dict = sh.convert_to_dict(inventory_dict)
118
  return inventory_dict, inventory_dict
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  #Function to dynamically render textbox if it has text.
121
  def update_visibility(textbox):
122
  if not textbox:
@@ -131,6 +193,28 @@ with gr.Blocks() as demo:
131
  store_name_output.change(fn=update_visibility,
132
  inputs=[store_name_output],
133
  outputs=[store_name_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  store_description_output = gr.Textbox(label = "Store Description", lines = 1, interactive = True, visible = True)
135
  store_description_output.change(fn=update_visibility,
136
  inputs=[store_description_output],
@@ -149,10 +233,11 @@ with gr.Blocks() as demo:
149
  store_specialties_output = gr.Textbox(label = "Specialties", lines = 1, interactive = True, visible = True)
150
  store_quests_output = gr.Textbox(label = "Quests", lines = 1, interactive = True, visible = True)
151
  store_rumors_output = gr.Textbox(label = "Rumors", lines = 1, interactive = True, visible = True)
 
152
 
153
 
154
  desc_gen.click(fn = gen_store_desc, inputs = [user_store_dict],
155
- outputs= [
156
  store_name, store_name_output,
157
  store_description, store_description_output,
158
  store_reputation, store_reputation_output,
@@ -168,7 +253,8 @@ with gr.Blocks() as demo:
168
  store_services,store_services_output,
169
  store_specialties,store_specialties_output,
170
  store_quests, store_quests_output,
171
- store_rumors, store_rumors_output
 
172
  ])
173
 
174
  image_path_list= u.absolute_path("./folder_with_images")
@@ -182,15 +268,23 @@ with gr.Blocks() as demo:
182
  inv_gen.click(fn = gen_store_inventory, inputs = [store_name, store_type, store_size, store_owner, store_reputation],
183
  outputs= [store_inventory, store_inventory_output
184
  ])
185
- dict_gen = gr.Button(value = "Click to convert test to data object")
186
  store_inventory_dict_output = gr.Textbox(label = 'Inventory', lines = 16, interactive=True, visible=True)
187
 
188
- dict_gen.click(fn = inventory_to_dict, inputs = [store_inventory_output],
189
  outputs= [store_inventory_dict, store_inventory_dict_output
190
  ])
191
 
192
 
193
  image_path_list= u.absolute_path("./folder_with_images")
 
 
 
 
 
 
 
 
194
  if __name__ == "__main__":
195
  demo.launch(allowed_paths=list_of_static_dir)
196
 
 
5
  import ctypes
6
  import store_helper as sh
7
  import process_text
8
+ import process_html
9
 
10
 
11
  # This is a fix for the way that python doesn't release system memory back to the OS and it was leading to locking up the system
 
16
  libc.mallopt(M_MMAP_THRESHOLD, 2**20)
17
 
18
  # Declare accessible directories
19
+ base_dir = os.path.dirname(os.path.abspath(__file__)) # Gets the directory where app.py is located
20
  print(f"Base Directory :",base_dir)
21
  list_of_static_dir = [os.path.join(base_dir, "output"),
22
  os.path.join(base_dir, "dependencies"),
23
  os.path.join(base_dir, "galleries")]
24
  gr.set_static_paths(paths=list_of_static_dir)
25
 
26
+
27
  # Build gradio app
28
  # Storing everything inside the Blocks to be accessible to the app
29
 
30
  with gr.Blocks() as demo:
31
  # Functions and State Variables
32
+ store_dict= gr.State()
33
  store_name = gr.State()
34
  store_description = gr.State()
35
  store_reputation = gr.State()
 
46
  notable_customers = gr.State()
47
  store_quests = gr.State()
48
  store_rumors = gr.State()
49
+ store_security = gr.State()
50
  store_inventory = gr.State()
51
  store_inventory_dict = gr.State()
 
52
  specialties_description = gr.State()
53
 
54
  def check_and_process_contents(item):
 
66
  # Key List for checking is speciufic keys are present before running parsing functions
67
  keys_list = list(llm_output)
68
  store_name_value = store_dict['store_name']
69
+ store_description_value = store_dict['store_description']
70
+ store_reputation_value = store_dict['store_reputation']
71
+ store_backstory_value = store_dict['store_backstory']
72
  store_sd_prompt_value = store_dict['store_sd_prompt']
73
+ store_type_value = store_dict['store_type']
74
+ store_size_value = store_dict['store_size']
75
+ store_location_value = check_and_process_contents(store_dict['store_location'])
76
+ store_owner_value = check_and_process_contents(store_dict['store_owners'])
77
+ store_employees_value = check_and_process_contents(store_dict['store_employees'])
78
  store_hours_value = store_dict['store_hours']
79
+ store_services_value = check_and_process_contents(store_dict['store_services'])
80
+ store_specialties_value = check_and_process_contents(store_dict['store_specialties'])
81
+ notable_customers_value = check_and_process_contents(store_dict['store_customers'])
82
+ store_quests_value = check_and_process_contents(store_dict['store_quests'])
83
+ store_rumors_value = check_and_process_contents(store_dict['store_rumors'])
84
+ store_security_value = check_and_process_contents(store_dict['store_security'])
85
 
86
 
87
  #Return each State variable twice, once to the variable and once to the textbox
88
+ return [store_dict, store_dict,
89
+ store_name_value, store_name_value,
90
  store_description_value, store_description_value,
91
  store_reputation_value, store_reputation_value,
92
  store_backstory_value, store_backstory_value,
 
101
  store_services_value, store_services_value,
102
  store_specialties_value, store_specialties_value,
103
  store_quests_value, store_quests_value,
104
+ store_rumors_value, store_rumors_value,
105
+ store_security_value, store_security_value
106
  ]
107
 
108
  def gen_store_inventory(store_name, store_type, store_size, store_owner, store_reputation):
109
  inventory_description = f"{store_name}, {store_type} {store_size} {store_owner} {store_reputation}"
110
  inventory_dict = sh.call_llm_and_cleanup(inventory_description, inventory=True)
111
  inventory_dict = sh.convert_to_dict(inventory_dict)
112
+ if inventory_dict['store_inventory']:
113
+ store_inventory_value = inventory_dict['store_inventory']
114
  store_inventory_value = process_text.format_inventory(store_inventory_value)
115
 
116
  #Return each State variable twice, once to the variable and once to the textbox
117
  return [store_inventory_value,store_inventory_value
118
  ]
119
+ def store_desc_to_dict(store_name,
120
+ store_description,
121
+ store_reputation,
122
+ store_backstory,
123
+ store_sd_prompt,
124
+ store_location,
125
+ store_type,
126
+ store_size,
127
+ store_owner,
128
+ store_employees,
129
+ store_hours,
130
+ store_services,
131
+ store_specialties,
132
+ notable_customers,
133
+ store_quests,
134
+ store_rumors,
135
+ store_security,
136
+ store_inventory
137
+ ):
138
+ store_dict = process_text.parse_text_to_store_dict(store_name,
139
+ store_description,
140
+ store_reputation,
141
+ store_backstory,
142
+ store_sd_prompt,
143
+ store_location,
144
+ store_type,
145
+ store_size,
146
+ store_owner,
147
+ store_employees,
148
+ store_hours,
149
+ store_services,
150
+ store_specialties,
151
+ notable_customers,
152
+ store_quests,
153
+ store_rumors,
154
+ store_security,
155
+ store_inventory)
156
+
157
+ # Process each variable and rebuild the store dict format, pass back as dictionary to the store_dict state variable.
158
+ store_dict = sh.convert_to_dict(store_dict)
159
+ return store_dict, store_dict
160
 
161
  def inventory_to_dict(inventory):
162
+ inventory_dict = process_text.parse_text_to_inventory_dict(inventory)
163
+ # Convert text format to data object dictionary and check for validity
164
  inventory_dict = sh.convert_to_dict(inventory_dict)
165
  return inventory_dict, inventory_dict
166
 
167
+ # Build html text by processing the generated dictionaries.
168
+ def build_html_file(store_dict):
169
+ template = process_html.dict_template
170
+ if store_dict == None:
171
+ store_dict = template
172
+
173
+ store_file_path = process_html.build_html_base(store_dict)
174
+
175
+ if not os.path.exists(store_file_path):
176
+ print(f"{store_file_path} not found")
177
+ else: print(f"{store_file_path} found")
178
+ iframe = f"""<iframe src="file={store_file_path}" width="100%" height="500px"></iframe>"""
179
+
180
+ return iframe
181
+
182
  #Function to dynamically render textbox if it has text.
183
  def update_visibility(textbox):
184
  if not textbox:
 
193
  store_name_output.change(fn=update_visibility,
194
  inputs=[store_name_output],
195
  outputs=[store_name_output])
196
+ store_dict_gen = gr.Button(value = "Click to convert test to data object")
197
+ store_dict_output = gr.Textbox(label = 'Inventory', lines = 16, interactive=True, visible=True)
198
+
199
+ store_dict_gen.click(fn = store_desc_to_dict, inputs = [store_name,
200
+ store_description,
201
+ store_reputation,
202
+ store_backstory,
203
+ store_sd_prompt,
204
+ store_location,
205
+ store_type,
206
+ store_size,
207
+ store_owner,
208
+ store_employees,
209
+ store_hours,
210
+ store_services,
211
+ store_specialties,
212
+ notable_customers,
213
+ store_quests,
214
+ store_rumors,
215
+ store_security,
216
+ store_inventory],
217
+ outputs= [store_dict, store_dict_output])
218
  store_description_output = gr.Textbox(label = "Store Description", lines = 1, interactive = True, visible = True)
219
  store_description_output.change(fn=update_visibility,
220
  inputs=[store_description_output],
 
233
  store_specialties_output = gr.Textbox(label = "Specialties", lines = 1, interactive = True, visible = True)
234
  store_quests_output = gr.Textbox(label = "Quests", lines = 1, interactive = True, visible = True)
235
  store_rumors_output = gr.Textbox(label = "Rumors", lines = 1, interactive = True, visible = True)
236
+ store_security_output = gr.Textbox(label = "Security", lines = 1, interactive = True, visible = True)
237
 
238
 
239
  desc_gen.click(fn = gen_store_desc, inputs = [user_store_dict],
240
+ outputs= [store_dict,store_dict,
241
  store_name, store_name_output,
242
  store_description, store_description_output,
243
  store_reputation, store_reputation_output,
 
253
  store_services,store_services_output,
254
  store_specialties,store_specialties_output,
255
  store_quests, store_quests_output,
256
+ store_rumors, store_rumors_output,
257
+ store_security, store_security_output
258
  ])
259
 
260
  image_path_list= u.absolute_path("./folder_with_images")
 
268
  inv_gen.click(fn = gen_store_inventory, inputs = [store_name, store_type, store_size, store_owner, store_reputation],
269
  outputs= [store_inventory, store_inventory_output
270
  ])
271
+ inv_dict_gen = gr.Button(value = "Click to convert test to data object")
272
  store_inventory_dict_output = gr.Textbox(label = 'Inventory', lines = 16, interactive=True, visible=True)
273
 
274
+ inv_dict_gen.click(fn = inventory_to_dict, inputs = [store_inventory_output],
275
  outputs= [store_inventory_dict, store_inventory_dict_output
276
  ])
277
 
278
 
279
  image_path_list= u.absolute_path("./folder_with_images")
280
+ with gr.Tab("HTML"):
281
+ with gr.Row():
282
+ with gr.Column():
283
+ gen_html = gr.Button(value = "Step 3 : Generate html")
284
+ html = gr.HTML(label="HTML preview", show_label=True)
285
+ gen_html.click(build_html_file,inputs =[store_dict],
286
+ outputs= html)
287
+
288
  if __name__ == "__main__":
289
  demo.launch(allowed_paths=list_of_static_dir)
290
 
process_html.py CHANGED
@@ -1,312 +1,425 @@
1
  import re, fileinput, sys
2
  import utilities as u
 
3
 
4
 
5
- import gradio as gr
 
 
 
 
 
6
 
7
- # HTML section headers
8
- actions_header = """<h4 id="actions">Actions</h4>
9
- """
10
- cantrips_header = """<h4 id="cantrips">Cantrips</h4>
11
- """
12
- spells_header = """<h4 id="known spells">Known Spells</h4>
13
- """
14
- spell_slot_header = """<h4 id="spell slots">Spell Slots</h4>
15
- """
16
- legendary_actions_header = """<h4 id="legendary actions">Legendary Actions</h4>
17
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
 
 
 
 
 
19
  # Assigning strings to variables for replacing location of dependencies for the webpage to local static folders
20
  # Path is ../../ for the html files location in output/dated_folder/
21
- break_tag = "<br>"
22
- def build_html_base(
23
- store_name,
24
- store_description,
25
- store_reputation,
26
- store_backstory,
27
- store_sd_prompt,
28
- store_location,
29
- store_type,
30
- store_size,
31
- store_owner,
32
- store_employees,
33
- store_hours,
34
- store_services,
35
- store_specialties,
36
- notable_customers,
37
- store_quests,
38
- store_rumors,
39
- store_inventory,
40
- store_inventory_dict
41
- ) :
42
-
43
-
44
 
45
- # Combine the properties that will go on a single line
46
- if mon_subtype != "" :
47
- mon_properties = f"{mon_size}, {mon_type}, {mon_subtype}, {mon_alignment}"
48
- else: mon_properties = f"{mon_size}, {mon_type}, {mon_alignment}"
49
- mon_abilities = parse_abilities_from_text(mon_abilities)
50
 
 
 
 
 
51
  # Template for the page
52
- html_base = f"""<!DOCTYPE html>
53
  <html>
54
- <head>
55
-
56
- <link href="../../dependencies/all.css" rel="stylesheet" />
57
- <link href="../../dependencies/css.css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
58
- <link href='../../dependencies/bundle.css' rel='stylesheet' />
59
- <link rel="icon" href="../../dependencies/favicon.ico" type="image/x-icon" />
60
- <title>{mon_name}</title>
61
- </head>
 
62
  <body>
63
- <link href='../../dependencies/style.css' rel='stylesheet' />
64
- <link href='../../dependencies/5ePHBstyle.css' rel='stylesheet' />
65
-
66
- <div class='brewRenderer'>
67
- <style>undefined</style>
68
- <div class='pages'>
69
- <div class='page phb' id='p1' key='0' >
70
- <div className='columnWrapper'>
71
- <div class="block monster frame wide" >
72
- <h4 id="user-monster-name">{mon_name}</h4>
73
- <p><em>{mon_properties}</em>
74
- <p><img class=" " style="width:330px; mix-blend-mode:multiply; border:3px solid black;" src={mon_image_path} alt="image"></p>
75
- <div class="block descriptive">
76
- <h5 id="user-monster-description">{mon_description}</h5>
77
-
78
- </div>
79
- <hr>
80
- <dl>
81
- <strong>Armor Class</strong> : {mon_armor_class}
82
- <strong>Hit Points</strong>: {mon_hp} Hit Dice : {mon_hit_dice}
83
- <strong>Speed</strong>: {mon_speed}
84
- </dl>
85
- <hr>
86
- <table>
87
- <thead>
88
- <tr>
89
- <th align=center>STR</th>
90
- <th align=center>DEX</th>
91
- <th align=center>CON</th>
92
- <th align=center>INT</th>
93
- <th align=center>WIS</th>
94
- <th align=center>CHA</th>
95
- </tr>
96
- </thead>
97
- <tbody>
98
- <tr>
99
- <td align=center>{mon_abilities[0]}</td>
100
- <td align=center>{mon_abilities[1]}</td>
101
- <td align=center>{mon_abilities[2]}</td>
102
- <td align=center>{mon_abilities[3]}</td>
103
- <td align=center>{mon_abilities[4]}</td>
104
- <td align=center>{mon_abilities[5]}</td>
105
- </tr>
106
- </tbody>
107
- </table>
108
- <hr>
109
- <strong>Saving Throws</strong> : {mon_saving_throws}
110
- <br><strong>Skills</strong> : {mon_skills}
111
- <br><strong>Resistances</strong> : {mon_damage_resistance}
112
- <br><strong>Senses</strong> : {mon_senses}
113
- <br><strong>Languages</strong> : {mon_languages}
114
- <br><strong>Challenge Rating</strong> : {mon_challenge_rating} ({mon_xp})"""
115
-
116
-
117
- if mon_actions :
118
- print("Actions : True")
119
- parsed_actions = parse_actions_from_text(mon_actions)
120
-
121
- html_file_as_text = f"""{html_base} <hr> {actions_header}
122
- {''.join(parsed_actions)}"""
123
- else:
124
- print("Actions : False")
125
- html_file_as_text = html_base
126
-
127
-
128
- if mon_cantrips:
129
- print(mon_cantrips)
130
- mon_cantrips = mon_cantrips.replace("Cantrips", '')
131
- mon_cantrips = parse_cantrips_from_text(mon_cantrips)
132
- html_file_as_text = html_file_as_text + cantrips_header + mon_cantrips
133
-
134
- if mon_spells :
135
- print(mon_spells)
136
- mon_spells = mon_spells.replace("Known Spells",'')
137
- mon_spells = parse_spells_from_text(mon_spells)
138
- html_file_as_text = html_file_as_text + spells_header + mon_spells
139
-
140
- if mon_spell_slots:
141
- print(mon_spell_slots)
142
- mon_spell_slots = mon_spell_slots.replace("Spell Slots", '')
143
- mon_spell_slots = parse_spell_slots_from_text(mon_spell_slots)
144
- html_file_as_text = html_file_as_text + spell_slot_header + mon_spell_slots
145
-
146
-
147
- else:
148
- print("Spells : False")
149
-
150
- if mon_legendary_actions:
151
- print("Legendary Actions : True")
152
- mon_legendary_actions = mon_legendary_actions.replace("Legendary Actions \n\n", '')
153
- mon_legendary_actions = parse_legendary_action_from_text(mon_legendary_actions)
154
- html_file_as_text = html_file_as_text +legendary_actions_header + mon_legendary_actions
155
- else:
156
- print("Legendary Actions : False")
157
 
158
- # Open a file path that will receive the processed text
159
- u.gen_file_name(mon_name)
160
- mon_file_path = f"{u.file_name_list[0]}/{u.file_name_list[1]}.html"
161
- with open(mon_file_path, 'w') as clean_html:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  clean_html.write(html_file_as_text)
163
  clean_html.close()
164
- # Clear link list and append with new entries
165
- del u.link_list[:]
166
- u.link_list.append(u.file_name_list[0]+'/' + u.file_name_list[1] +'.html')
167
- u.link_list.append(mon_type)
168
-
169
- #Passing back a file path that Gradio can access and is local
170
- return mon_file_path
171
-
172
- def parse_actions_from_text(edited_text):
173
- html_content = '<dl>'
174
- actions = []
175
- action_entries = edited_text.strip().split('\n\n')
176
- print(action_entries)
177
- for entry in action_entries:
178
- parts = entry.split(';')
179
- action_dict = {
180
- "name": parts[0].split(": ")[1].strip(),
181
- "desc": parts[1].split("Description: ")[1].strip()
182
- }
183
- actions.append(action_dict)
184
-
185
- for action in actions:
186
- html_content += f"<dt><em><strong>{action['name']}</strong></em> :</dt><dd>‘{action['desc']}</dd>"
187
- html_content += "<br>"
188
- html_content=html_content.rstrip('br')
189
-
190
- html_content += '</dl>'
191
- return html_content
192
-
193
- def parse_abilities_from_text(abilities):
194
- abilities_list = []
195
- ability_entries = abilities.strip().split('\n')
196
- for entry in ability_entries:
197
- parts = entry.split(':')
198
- ability_value = parts[1]
199
- abilities_list.append(ability_value)
200
- return abilities_list
201
-
202
- def parse_cantrips_from_text(cantrips):
203
- html_content = '<dl>'
204
- cantrips_list = []
205
- cantrip_entries = cantrips.strip().split('\n\n')
206
- for entry in cantrip_entries:
207
- parts = entry.split(';')
208
- cantrip_dict = {
209
- "name": parts[0],
210
- "desc": parts[1].split("Description: ")[1].strip()
211
- }
212
- cantrips_list.append(cantrip_dict)
213
- for cantrip in cantrips_list:
214
- html_content += f"<dt><em><strong>{cantrip['name']}</strong></em> :</dt> <dd> ‘{cantrip['desc']}’</dd>"
215
- html_content += "<br>"
216
- html_content=html_content.rstrip('br')
217
- html_content += '</dl>'
218
- return html_content
219
-
220
- def parse_spells_from_text(spells):
221
- html_content = '<dl>'
222
- spells_list = []
223
- spell_entries = spells.strip().split('\n\n')
224
- for entry in spell_entries:
225
- print(f"Spell entry = {entry}")
226
- parts = entry.split(';')
227
- spell_name_part = parts[0]
228
- level_desc_part = parts[1]
229
-
230
- # Extract the spell's name (before 'level:')
231
- name = spell_name_part.strip()
232
-
233
- # Further split level and description
234
- level_part = level_desc_part.split(", Description:")[0].strip()
235
- description_part = level_desc_part.split(", Description:")[1].strip() if ", Description:" in level_desc_part else ""
236
-
237
- # Extract the level (assuming it follows 'Level: ' directly)
238
- level = level_part.replace("Level: ", "").strip()
239
- print(f"Level = {level}")
240
-
241
-
242
- # Assemble the dictionary for this spell
243
- spell_dict = {
244
- "name": name,
245
- "level": level,
246
- "desc": description_part
247
- }
248
- spells_list.append(spell_dict)
249
- for spell in spells_list:
250
- html_content += f"<dt><em><strong>{spell['name']}</strong></em> :</dt> <dd> ‘Level : {spell['level']} {spell['desc']}’</dd>"
251
- html_content += " <br>"
252
- html_content=html_content.rstrip('br')
253
- html_content += '</dl>'
254
- return html_content
255
-
256
- def parse_spell_slots_from_text(spell_slots):
257
- html_content = '<dl>'
258
- spell_slots_list = []
259
- spell_slot_entries = spell_slots.strip().split('\n\n')
260
- for entry in spell_slot_entries:
261
-
262
- if '0' not in entry:
263
- parts = entry.split(':')
264
- spell_slot_dict = {
265
- "level": parts[0],
266
- "number": parts[1]
267
-
268
- }
269
-
270
- spell_slots_list.append(spell_slot_dict)
271
- for spell_slot in spell_slots_list:
272
- html_content += f"<dt><em><strong>{spell_slot['level']}</strong></em>:</dt> <dd>‘{spell_slot['number']}’</dd>"
273
- html_content += " <br>"
274
- html_content=html_content.rstrip(' br')
275
- html_content += '</dl>'
276
- return html_content
277
-
278
- def parse_legendary_action_from_text(legendary_actions):
279
- html_content = '<dl>'
280
- parts = legendary_actions.split('\n\n')
281
- description = parts[0].strip()
282
- description = description + "<br>"
283
- print(f"Description : {description}")
284
- actions_text = parts[1:]
285
- actions = ';'.join(actions_text)
286
- actions = actions.split(';')
287
- print(f"actions : {actions}")
288
-
289
- legendary_actions_dict = {
290
- "description": description,
291
- "actions":[]
292
- }
293
- html_content += description
294
- # Process each action
295
- for action in actions:
296
- print(f"action to be parsed: {action}")
297
- action_split = action.split(':')
298
- print(f"Split Action : {action_split}")
299
- legendary_actions_dict['actions'].append({
300
- "name": action_split[0],
301
- "desc": action_split[1]
302
- })
303
-
304
- for action in legendary_actions_dict['actions']:
305
- print(action)
306
- html_content += f"<dt><em><strong>{action['name']}</strong></em>:</dt> <dd> ‘{action['desc']}’</dd>"
307
- html_content += " <br>"
308
- html_content=html_content.rstrip(' br')
309
- html_content += '</dl>'
310
- return html_content
311
 
 
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import re, fileinput, sys
2
  import utilities as u
3
+ import os
4
 
5
 
6
+ def list_names_to_str(data):
7
+ list_of_names = []
8
+ for i in data:
9
+ list_of_names.append(i['name'])
10
+ str_of_names = ', '.join(list_of_names)
11
+ return str_of_names
12
 
13
+ def list_to_str(list):
14
+ str_of_list = ', '.join(list)
15
+ return str_of_list
16
+ def build_owners_section(owners_list):
17
+ owner_s = 'Owner'
18
+ if len(owners_list) > 1 :
19
+ owner_s = 'Owners'
20
+ owner_section_html = f"""<h2 id="owner">{owner_s}</h2> """
21
+ # iterating through list of owners, each is a dictionary with descriptive qualities
22
+ for owner in range(len(owners_list)) :
23
+ secrets = '<br> '.join(owners_list[owner - 1]['secrets'])
24
+ owner_section_html += f"""
25
+ <h3 id="owner_{owner}">{owners_list[owner - 1]['name']}</h3>
26
+ <table>
27
+ <thead>
28
+ <tr>
29
+ <th align="center"></th>
30
+ <th align="center"></th>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ <tr>
35
+ <td align="center"><strong>Species</strong></td>
36
+ <td align="right">{owners_list[owner - 1]['species']}</td>
37
+ </tr>
38
+ <tr>
39
+ <td align="center"><strong>Class</strong></td>
40
+ <td align="right">{owners_list[owner - 1]['class']}</td>
41
+ </tr>
42
+ <tr>
43
+ <td align="center"><strong>Description</strong></td>
44
+ <td align="left">{owners_list[owner - 1]['description']}.</td>
45
+ </tr>
46
+ <tr>
47
+ <td align="center"><strong>Personality</strong></td>
48
+ <td align="left">{owners_list[owner - 1]['personality']}</td>
49
+ </tr>
50
+ <tr>
51
+ <td align="center"><strong>Secrets</strong></td>
52
+ <td align="left">{secrets}</td>
53
+ </tr>
54
+ </tbody>
55
+ </table>
56
+ """
57
+ return owner_section_html
58
 
59
+
60
+
61
+ store_image_url = ""
62
+
63
+
64
  # Assigning strings to variables for replacing location of dependencies for the webpage to local static folders
65
  # Path is ../../ for the html files location in output/dated_folder/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ def build_html_base(store_dict) :
 
 
 
 
68
 
69
+ base_dir = os.path.dirname(os.path.abspath(__file__))
70
+ dependencies_path = os.path.relpath(os.path.join(base_dir, "dependencies"), os.path.join(base_dir, "output", "test"))
71
+
72
+
73
  # Template for the page
74
+ html_file_as_text = f"""<!DOCTYPE html>
75
  <html>
76
+ <head>
77
+ <link href="{dependencies_path}/all.css" rel="stylesheet" />
78
+ <link href="{dependencies_path}/css.css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
79
+ <link href="{dependencies_path}/bundle.css" rel="stylesheet" />
80
+ <link rel="icon" href="{dependencies_path}/favicon.ico" type="image/x-icon" />
81
+ <link href="{dependencies_path}/style.css" rel="stylesheet" />
82
+ <link href="{dependencies_path}/5ePHBstyle.css" rel="stylesheet" />
83
+ <title>{store_dict['store_name']}</title>
84
+ </head>
85
  <body>
86
+ <div>
87
+ <div class="brewRenderer" style="height: 692px;">
88
+ <div class="pages" lang="en">
89
+ <div class="page" id="p1">
90
+ <div class="columnWrapper">
91
+ <h1 id="store_name">{store_dict['store_name']}</h1>
92
+ <p>{store_dict['store_description']}</p>
93
+ <p>{store_dict['store_backstory']}</p>
94
+ <p>{store_dict['store_reputation']}</p>
95
+ <!-- Generated Image of Shop -->
96
+ <p><img class="" style="width:300px; mix-blend-mode:multiply;" src="{store_image_url}" alt="{store_dict['store_name']}"></p>
97
+ <div class="block classTable frame decoration">
98
+ <table>
99
+ <thead>
100
+ <tr>
101
+ <th align="left"></th>
102
+ <th align="center"></th>
103
+ <th align="center"></th>
104
+ </tr>
105
+ </thead>
106
+ <tbody>
107
+ <tr>
108
+ <td align="left"><strong>Size</strong></td>
109
+ <td align="right">{store_dict['store_size']}</td>
110
+ </tr>
111
+ <tr>
112
+ <td align="left"><strong>Town</strong></td>
113
+ <td align="right">{store_dict['store_location']['town']}</td>
114
+ </tr>
115
+ <tr>
116
+ <td align="left"><strong>District</strong></td>
117
+ <td align="right">{store_dict['store_location']['district']}</td>
118
+ </tr>
119
+ <tr>
120
+ <td align="left"><strong>Street</strong></td>
121
+ <td align="right">{store_dict['store_location']['street']}</td>
122
+ </tr>
123
+ <tr>
124
+ <td align="left"><strong>Type</strong></td>
125
+ <td align="right">{store_dict['store_type']}</td>
126
+ </tr>
127
+ <tr>
128
+ <td align="left"><strong>Owners</strong></td>
129
+ <td align="right">{list_names_to_str(store_dict['store_owners'])}</td>
130
+ </tr>
131
+ <tr>
132
+ <td align="left"><strong>Employees</strong></td>
133
+ <td align="right">{list_names_to_str(store_dict['store_employees'])}</td>
134
+ </tr>
135
+ <tr>
136
+ <td align="left"><strong>Store Hours</strong></td>
137
+ <td align="right">{store_dict['store_hours']}</td>
138
+ </tr>
139
+ <tr>
140
+ <td align="left"><strong>Services</strong></td>
141
+ <td align="right">{list_names_to_str(store_dict['store_services'])}</td>
142
+ </tr>
143
+ <tr>
144
+ <td align="left"><strong>Specialties</strong></td>
145
+ <td align="right">{list_names_to_str(store_dict['store_specialties'])}</td>
146
+ </tr>
147
+ <tr>
148
+ <td align="left"><strong>Reputation</strong></td>
149
+ <td align="right">{store_dict['store_reputation']}</td>
150
+ </tr>
151
+ <tr>
152
+ <td align="left"><strong>Rumors</strong></td>
153
+ <td align="right">{list_to_str(store_dict['store_rumors'])}</td>
154
+ </tr>
155
+ </tbody>
156
+ </table>
157
+ </div>
158
+ <p><img class="" style="width:300px; mix-blend-mode:multiply;" src="https://media.githubusercontent.com/media/Drakosfire/StoreGenerator/master/galleries/test_images/Morgor_bloodclaw.png" alt="{store_dict['store_owners'][0]['name']}"></p>
159
+ {build_owners_section(store_dict['store_owners'])}
160
+
161
+
162
+ <p>&nbsp;</p>
163
+ <div class="columnSplit"></div>
164
+ <p>&nbsp;</p>
165
+ </div>
166
+ </div>
167
+ <div class="page" id="p2">
168
+ <div class="columnWrapper">
169
+ <div class="blank"></div>
170
+ <h2 id="employees">Employees</h2>
171
+
172
+ <h3 id="brega">Brega</h3>
173
+ <p><img class="" style="width:150px; mix-blend-mode:multiply;" src="https://media.githubusercontent.com/media/Drakosfire/StoreGenerator/master/galleries/test_images/Brega.png" alt="Brega"></p>
 
 
 
 
 
 
174
 
175
+ <table>
176
+ <thead>
177
+ <tr>
178
+ <th align="center"></th>
179
+ <th align="center"></th>
180
+ </tr>
181
+ </thead>
182
+ <tbody>
183
+ <tr>
184
+ <td align="center"><strong>Species</strong></td>
185
+ <td align="center">Half-Orc</td>
186
+ </tr>
187
+ <tr>
188
+ <td align="center"><strong>Class</strong></td>
189
+ <td align="center">Assistant Butcher</td>
190
+ </tr>
191
+ <tr>
192
+ <td align="center"><strong>Description</strong></td>
193
+ <td align="center">A burly half-orc with a kind face and a perpetual smudge of blood on his cheek. Brega handles the heavy lifting and cutting of larger beasts.</td>
194
+ </tr>
195
+ <tr>
196
+ <td align="center"><strong>Personality</strong></td>
197
+ <td align="center">Soft-spoken and gentle despite his imposing appearance, Brega is loyal to Morgor and respects his cunning. He has a soft spot for stray animals.</td>
198
+ </tr>
199
+ </tbody>
200
+ </table>
201
+
202
+ <div class="block">
203
+ <h1 id="notable-customers">Notable Customers</h1>
204
+ <div class="block note">
205
+ <h3 id="lord-vittorio-blackthorn">Lord Vittorio Blackthorn</h3>
206
+ <p>An eccentric noble known for his extravagant feasts featuring rare and exotic meats.</p>
207
+ <p>Lord Blackthorn’s patronage lends an air of mystery and prestige to Morgor’s shop, attracting curious gourmands and shady characters alike.</p>
208
+ </div>
209
+ <h1 id="related-quests">Related Quests</h1>
210
+ <h3 id="the-basilisk-bounty">The Basilisk Bounty</h3>
211
+ <p>Morgor needs fresh basilisk meat and offers a handsome reward for those brave enough to hunt one.</p>
212
+ <p>500 gold coins and choice cuts of meat.</p>
213
+ </div>
214
+
215
+
216
+ <div class="columnSplit"></div>
217
+ <div class="block">
218
+ <h1 id="services-and-specialties">Services and Specialties</h1>
219
+ <div class="blank"></div>
220
+ <h2 id="services">Services</h2>
221
+ <h3 id="custom-slaughtering">Custom Slaughtering</h3>
222
+ <p>Bring your own beasts, and Morgor will prepare the meat to your specifications.
223
+ 50 gold coins per beast.</p>
224
+ <div class="blank"></div>
225
+ <h2 id="specialties">Specialties</h2>
226
+ <div class="blank"></div>
227
+ <h3 id="basilisk-cutlets">Basilisk Cutlets</h3>
228
+ <p>Tender and marbled with a unique flavor, perfect for those seeking a truly rare dining experience.</p>
229
+ <h3 id="subterranean-lizard-tail">Subterranean Lizard Tail</h3>
230
+ <p>A delicacy prized for its unique texture and earthy taste, enchanted to enhance its natural flavor.</p>
231
+ <h1 id="security">Security</h1>
232
+ <div class="blank"></div>
233
+ <h3 id="bewitched-meat-hooks">Bewitched Meat Hooks</h3>
234
+ <p>These enchanted meat hooks animate and attack intruders who try to take meat without paying. 200 gold coins per pound.</p>
235
+ <div class="blank"></div>
236
+ <p>Attack: +5 to hit, 1d8+3 piercing damage.</p>
237
+ <h3 id="shadow-ward">Shadow Ward</h3>
238
+ <p>A magical barrier that alerts Morgor if someone enters the shop after hours. 150 gold coins per pound.</p>
239
+ <div class="blank"></div>
240
+ <p>Detection radius of 60 feet, triggers an audible alarm.</p>
241
+ </div> <!-- Close Block -->
242
+ </div> <!-- close columnWrapper-->
243
+ </div> <!-- close page 2 -->
244
+
245
+ <div class="page" id="p3">
246
+ <div class="columnWrapper">
247
+
248
+ <div class="block classTable frame decoration">
249
+ <h5 id="inventory">Inventory</h5>
250
+ <table>
251
+ <thead>
252
+ <tr>
253
+ <th align="center">Name</th>
254
+ <th align="center">Type</th>
255
+ <th align="left">Cost</th>
256
+ <th align="center">Properties</th>
257
+ </tr>
258
+ </thead>
259
+ <tbody>
260
+ <tr>
261
+ <td align="center">Poultry Drumsticks</td>
262
+ <td align="center">Meat</td>
263
+ <td align="left">1 gp per lbs</td>
264
+ <td align="center"></td>
265
+ </tr>
266
+ <tr>
267
+ <td align="center">Ground Beef</td>
268
+ <td align="center">Meat</td>
269
+ <td align="left">1 gp per lbs</td>
270
+ <td align="center"></td>
271
+ </tr>
272
+ <tr>
273
+ <td align="center">Pork Chops</td>
274
+ <td align="center">Meat</td>
275
+ <td align="left">1 gp per lbs</td>
276
+ <td align="center"></td>
277
+ </tr>
278
+ <tr>
279
+ <td align="center">Bacon Strips</td>
280
+ <td align="center">Meat</td>
281
+ <td align="left">1 gp per lbs</td>
282
+ <td align="center"></td>
283
+ </tr>
284
+ <tr>
285
+ <td align="center">Sausage Links</td>
286
+ <td align="center">Meat</td>
287
+ <td align="left">1 gp per lbs</td>
288
+ <td align="center"></td>
289
+ </tr>
290
+ <tr>
291
+ <td align="center">Mystic Minotaur Steak</td>
292
+ <td align="center">Exotic Meat</td>
293
+ <td align="left">25 gold per pound</td>
294
+ <td align="center">Grants temporary strength boost when consumed, Requires fine culinary skills to cook properly</td>
295
+ </tr>
296
+ <tr>
297
+ <td align="center">Quantum Quail</td>
298
+ <td align="center">Exotic Poultry</td>
299
+ <td align="left">15 gold each</td>
300
+ <td align="center">“Phases in and out of existence”, “Can enhance one’s agility”</td>
301
+ </tr>
302
+ <tr>
303
+ <td align="center">Invisible Bacon</td>
304
+ <td align="center">Mystical Meat</td>
305
+ <td align="left">10 gold per slice</td>
306
+ <td align="center">“Invisible to the naked eye”, “Tastes incredibly savory”, “Can only be seen with a special spell”</td>
307
+ </tr>
308
+ <tr>
309
+ <td align="center">Hydra Sausage</td>
310
+ <td align="center">Mythical Meat</td>
311
+ <td align="left">50 gold per link</td>
312
+ <td align="center">“Each bite regenerates after a while”, “Consuming too much may cause mild hallucinations”</td>
313
+ </tr>
314
+ <tr>
315
+ <td align="center">Cursed Cleaver</td>
316
+ <td align="center">Kitchen Equipment</td>
317
+ <td align="left">100 gold</td>
318
+ <td align="center">“Cuts through any meat effortlessly”, “Occasionally whispers in a long-forgotten language”, “Rumored to be haunted”</td>
319
+ </tr>
320
+ <tr>
321
+ <td align="center">Vampire Spice Mix</td>
322
+ <td align="center">Cooking Ingredient</td>
323
+ <td align="left">20 gold per pouch</td>
324
+ <td align="center">“Adds a distinct flavor”, “Enhances blood flow in the consumer”, “Leaves a lingering aftertaste of garlic”</td>
325
+ </tr>
326
+ <tr>
327
+ <td align="center">Phoenix Feather Skewers</td>
328
+ <td align="center">Cooking Utensil</td>
329
+ <td align="left">75 gold per set</td>
330
+ <td align="center">“Prevents meat from overcooking”, “Gives a slight warmth to cooked items”, “Reusable endlessly”</td>
331
+ </tr>
332
+ </tbody>
333
+ </table>
334
+ </div>
335
+ <p>&nbsp;</p>
336
+ </div><!-- Close Column Wrapper-->
337
+ </div> <!-- Close Page 3-->
338
+ </div> <!-- Close pages-->
339
+ </div> <!--Close brew renderer-->
340
+ </div><!-- Close Div housing body-->
341
+ </body>
342
+ </html>"""
343
+ # Open a file path that will receive the processed text
344
+ store_file_path = f"output/test/{store_dict['store_name'].replace(' ', '_')}.html"
345
+ with open(store_file_path, 'w') as clean_html:
346
  clean_html.write(html_file_as_text)
347
  clean_html.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
 
349
+ return store_file_path
350
 
351
+ dict_template = {
352
+ "store_name": "The Mirage Emporium",
353
+ "store_description": "A peculiar shop filled with the odd and the useless, where each corner hides a laugh and a mystery.",
354
+ "store_reputation": "Locally famous for its bizarre and delightful inventory, though not particularly useful.",
355
+ "store_backstory": "The Mirage Emporium was founded by a retired jester known for his love of the whimsical and the curious. He traveled the world collecting oddball items that struck his fancy, and upon amassing a considerable collection, opened a shop to share his treasures with the world.",
356
+ "store_sd_prompt": "A highly detailed fantasy illustration of a middle-aged full body male gnome in an eclectic shop. The gnome is wearing a colorful patchwork vest and a jaunty hat. The shop is filled with quirky items like broken clocks, mismatched shoes, and joke books. The gnome has distinct fantasy features, such as pointed ears and a small, sturdy build. The background is a vibrant mix of colors and textures, giving the impression of organized chaos.",
357
+ "store_type": "Curiosity Shop",
358
+ "store_size": "Small",
359
+ "store_hours": "From dawn until the moonlight dances.",
360
+ "store_location": {
361
+ "town": "Bramblebrook",
362
+ "district": "Harlequin Quarter",
363
+ "street": "Twilight Alley"
364
+ },
365
+ "store_owners": [
366
+ {
367
+ "name": "Fizzwidget Funsquirrel",
368
+ "species": "Gnome",
369
+ "class": "Bard",
370
+ "description": "A lively gnome with a perpetual twinkle in his eye and a knack for making people smile.",
371
+ "personality": "Joyful, playful, and a tad mischievous.",
372
+ "secrets": ["Fizzwidget once performed a jester act for the Queen of Faerun.", "He has a hidden collection of practical jokes for special customers."],
373
+ "sd_prompt": "A highly detailed fantasy illustration of a cheerful full body male gnome in an eclectic shop. The gnome is wearing a colorful patchwork vest and a jaunty hat, with a playful expression and sparkling eyes. The shop is filled with quirky items and the background is a chaotic mix of vibrant colors and textures."
374
+ }
375
+ ],
376
+ "store_employees": [
377
+ {
378
+ "name": "Marigold Merryleaf",
379
+ "role": "Shop Assistant",
380
+ "species": "Halfling",
381
+ "description": "A spry halfling with a knack for finding peculiar trinkets buried under heaps of clutter.",
382
+ "personality": "Curious, quirky, and always up for a laugh.",
383
+ "sd_prompt": "A highly detailed fantasy illustration of a spry full body female halfling in an eclectic shop. The halfling is wearing a colorful apron and has a curious expression. The shop is filled with quirky items, and the background is a chaotic mix of vibrant colors and textures."
384
+ }
385
+ ],
386
+ "store_quests": [
387
+ {
388
+ "name": "The Great Sock Hunt",
389
+ "description": "Help Fizzwidget locate a rare pair of mismatched socks rumored to bring joy and luck, hidden somewhere in the town of Bramblebrook.",
390
+ "reward": "A pair of enchanted socks that make the wearer extraordinarily lucky in games of chance."
391
+ }
392
+ ],
393
+ "store_customers": [
394
+ {
395
+ "name": "Lord Twiddleton",
396
+ "description": "An eccentric noble who collects oddities and revels in the unusual.",
397
+ "influence": "High, due to his noble status and wealth."
398
+ }
399
+ ],
400
+ "store_rumors": [
401
+ "It's said that Fizzwidget once outwitted a dragon using only a rubber chicken and a whoopee cushion.",
402
+ "Marigold can find lost items using her 'half-sense' for where things hide."
403
+ ],
404
+ "store_security": [
405
+ {
406
+ "name": "Gizmo Gearshaft",
407
+ "description": "An ingenious contraption that includes clockwork gears, springs, and enchanted runes.",
408
+ "mechanics": "Gizmo Gearshaft patrols the shop, alert for intruders and mischief-makers, and can deploy harmless yet startling pranks to deter trouble."
409
+ }
410
+ ],
411
+ "store_services": [
412
+ {
413
+ "name": "Laughter Therapy",
414
+ "description": "A session with Fizzwidget who tells jokes and performs tricks to brighten your day.",
415
+ "price": "1 gold coin per session"
416
+ }
417
+ ],
418
+ "store_specialties": [
419
+ {
420
+ "name": "Mystery Mounds",
421
+ "description": "A pile of assorted oddities bundled together; you never know what you'll get, but it'll always be a conversation starter!",
422
+ "price": "5 silver per bundle"
423
+ }
424
+ ]
425
+ }
process_text.py CHANGED
@@ -1,8 +1,55 @@
1
 
2
- #Function to process text from Key Value pairs into User Friendly text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
 
 
 
 
 
 
4
  def format_qualities(qualities):
5
- print(f"Formatting Start,{type(qualities)} ")
6
  formatted_text = ""
7
  if type(qualities) == list:
8
  # print("List")
@@ -13,8 +60,8 @@ def format_qualities(qualities):
13
  if type(value) == list:
14
  formatted_text += f"{key} : "
15
  for i in value:
16
- formatted_text += i
17
- formatted_text = formatted_text.rstrip(",")
18
  formatted_text += "\n"
19
 
20
  else :
@@ -25,13 +72,15 @@ def format_qualities(qualities):
25
  if type(item) == list:
26
  # print("List item List")
27
  for i in item:
28
- formatted_text += i
 
29
  if type(item) == str:
30
- # print("List item Str")
31
- formatted_text += f"{item}\n"
 
32
 
33
- formatted_text = formatted_text.rstrip(",")
34
- formatted_text += "\n"
35
  return formatted_text
36
 
37
  elif type(qualities) == dict:
@@ -40,6 +89,102 @@ def format_qualities(qualities):
40
  formatted_text = formatted_text.rstrip(",")
41
  return formatted_text
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  def format_inventory(inventory):
44
  formatted_text = ""
45
  print(f"Formatting Inventory ,{type(inventory)} ")
@@ -66,7 +211,8 @@ def format_inventory(inventory):
66
 
67
  return formatted_text
68
 
69
- def parse_text_to_inventory(data):
 
70
  inventory_categories = [
71
  "core_inventory",
72
  "weapons",
@@ -85,12 +231,12 @@ def parse_text_to_inventory(data):
85
 
86
  for line in lines:
87
  line = line.strip()
88
- print(f"line = {line}")
89
  if not line:
90
  continue
91
 
92
  if line in inventory_categories:
93
- print(f"Current Category : {line}")
94
  current_category = f"{line}"
95
  inventory[f"{current_category}"] = []
96
 
@@ -98,7 +244,7 @@ def parse_text_to_inventory(data):
98
  if current_item:
99
  inventory[f"{current_category}"].append(current_item)
100
  current_item = {"name": line.split(":")[1].strip(", ")}
101
- print(current_item)
102
 
103
  elif ":" in line:
104
  key, value = line.split(":")
@@ -108,7 +254,7 @@ def parse_text_to_inventory(data):
108
  value = [v.strip().strip("'") for v in value.split(",")]
109
  current_item[key] = value
110
 
111
- print(f"Inventory Dictionary = {inventory}")
112
 
113
  if current_item:
114
  inventory[current_category].append(current_item)
 
1
 
2
+ # split text along : into key values.
3
+ def dict_from_text(data):
4
+ lines = data.strip().split("\n")
5
+ current_item = {}
6
+ for line in lines:
7
+ if ":" in line:
8
+ key, value = line.split(":")
9
+ key = key.strip()
10
+ value = value.strip(", ")
11
+ current_item[key] = value
12
+ return current_item
13
+
14
+ def list_of_dict_from_text(data):
15
+
16
+ lines = data.strip().split("\n")
17
+ output_list = []
18
+ # current_category = None
19
+ current_item = {}
20
+
21
+ for line in lines:
22
+ line = line.strip()
23
+ # print(f"line = {line}")
24
+ if not line:
25
+ continue
26
+ if "name :" in line:
27
+ if current_item:
28
+ output_list.append(current_item)
29
+ current_item = {"name": line.split(":")[1].strip(", ")}
30
+
31
+ elif ":" in line:
32
+ key, value = line.split(":")
33
+ key = key.strip()
34
+ value = value.strip(", ")
35
+ if key == "secrets" :
36
+ value = list_from_text(value)
37
+ current_item[key] = value
38
+
39
+ if current_item:
40
+ output_list.append(current_item)
41
+
42
+ return output_list
43
 
44
+ def list_from_text(data):
45
+ # print(f"Incoming Text: {data}")
46
+ value = [v.strip().strip("'").strip("\n") for v in data.split(",")]
47
+ # print(f"Returned List : {value}")
48
+ return value
49
+
50
+ #Function to process text from Key Value pairs into User Friendly text in a format that can be converted back to a dictionary
51
  def format_qualities(qualities):
52
+ # print(f"Formatting Start,{type(qualities)} ")
53
  formatted_text = ""
54
  if type(qualities) == list:
55
  # print("List")
 
60
  if type(value) == list:
61
  formatted_text += f"{key} : "
62
  for i in value:
63
+ formatted_text += f"{i} , "
64
+ formatted_text = formatted_text.rstrip(" ,")
65
  formatted_text += "\n"
66
 
67
  else :
 
72
  if type(item) == list:
73
  # print("List item List")
74
  for i in item:
75
+ formatted_text += f"{i} , "
76
+ formatted_text = formatted_text.rstrip(" ,")
77
  if type(item) == str:
78
+ print(f"List : {item}")
79
+ formatted_text += f"{item} , "
80
+
81
 
82
+ formatted_text = formatted_text.rstrip(",").rstrip(" ,")
83
+ formatted_text += "\n "
84
  return formatted_text
85
 
86
  elif type(qualities) == dict:
 
89
  formatted_text = formatted_text.rstrip(",")
90
  return formatted_text
91
 
92
+ def parse_text_to_store_dict(store_name,
93
+ store_description,
94
+ store_reputation,
95
+ store_backstory,
96
+ store_sd_prompt,
97
+ store_location,
98
+ store_type,
99
+ store_size,
100
+ store_owner,
101
+ store_employees,
102
+ store_hours,
103
+ store_services,
104
+ store_specialties,
105
+ store_customers,
106
+ store_quests,
107
+ store_rumors,
108
+ store_security,
109
+ store_inventory):
110
+
111
+ # Print variable, and check it's value and if length greater than 0.
112
+ # Check for dict, str, list
113
+
114
+
115
+ print(f"{store_inventory}")
116
+
117
+ # Parse store description key : values with string values first
118
+ store_dict = {}
119
+ if store_name :
120
+ store_dict['store_name'] = store_name
121
+ else: store_dict['store_name'] = ""
122
+
123
+ if store_description :
124
+ store_dict['store_description'] = store_description
125
+ else: store_dict['store_description'] = ""
126
+
127
+ if store_reputation :
128
+ store_dict['store_reputation'] = store_reputation
129
+ else: store_dict['store_reputation'] = ""
130
+
131
+ if store_backstory :
132
+ store_dict['store_backstory'] = store_backstory
133
+ else: store_dict['store_backstory'] = ""
134
+
135
+ if store_type :
136
+ store_dict['store_type'] = store_type
137
+ else: store_dict['store_type'] = ""
138
+
139
+ if store_size :
140
+ store_dict['store_size'] = store_size
141
+ else: store_dict['store_size'] = ""
142
+
143
+ if store_hours :
144
+ store_dict['store_hours'] = store_hours
145
+ else: store_dict['store_hours'] = ""
146
+
147
+ if store_sd_prompt :
148
+ store_dict['store_sd_prompt'] = store_sd_prompt
149
+ else: store_dict['store_sd_prompt'] = ""
150
+
151
+ if store_location :
152
+ store_dict['store_location'] = dict_from_text(store_location)
153
+ else: store_dict['store_location'] = ''
154
+
155
+ if store_owner :
156
+ store_dict['store_owners'] = list_of_dict_from_text(store_owner)
157
+ else: store_dict['store_owners'] = ''
158
+
159
+ if store_employees :
160
+ store_dict['store_employees'] = list_of_dict_from_text(store_employees)
161
+ else: store_dict['store_employees'] = ''
162
+
163
+ if store_quests :
164
+ store_dict['store_quests'] = list_of_dict_from_text(store_quests)
165
+ else: store_dict['store_quests'] = ''
166
+
167
+ if store_customers :
168
+ store_dict['store_customers'] = list_of_dict_from_text(store_customers)
169
+ else: store_dict['store_customers'] = ''
170
+
171
+ if store_rumors :
172
+ store_dict['store_rumors'] = list_from_text(store_rumors)
173
+
174
+ if store_services :
175
+ store_dict['store_services'] = list_of_dict_from_text(store_services)
176
+ else: store_dict['store_services'] = ''
177
+
178
+ if store_specialties :
179
+ store_dict['store_specialties'] = list_of_dict_from_text(store_specialties)
180
+ else: store_dict['store_specialties'] = ''
181
+
182
+ if store_security :
183
+ store_dict['store_security'] = list_of_dict_from_text(store_security)
184
+ else: store_dict['store_security'] = ''
185
+
186
+ return store_dict
187
+
188
  def format_inventory(inventory):
189
  formatted_text = ""
190
  print(f"Formatting Inventory ,{type(inventory)} ")
 
211
 
212
  return formatted_text
213
 
214
+ # Take in the text from the inventory textbox, and reformat into a dictionary object
215
+ def parse_text_to_inventory_dict(data):
216
  inventory_categories = [
217
  "core_inventory",
218
  "weapons",
 
231
 
232
  for line in lines:
233
  line = line.strip()
234
+ # print(f"line = {line}")
235
  if not line:
236
  continue
237
 
238
  if line in inventory_categories:
239
+ # print(f"Current Category : {line}")
240
  current_category = f"{line}"
241
  inventory[f"{current_category}"] = []
242
 
 
244
  if current_item:
245
  inventory[f"{current_category}"].append(current_item)
246
  current_item = {"name": line.split(":")[1].strip(", ")}
247
+ # print(current_item)
248
 
249
  elif ":" in line:
250
  key, value = line.split(":")
 
254
  value = [v.strip().strip("'") for v in value.split(",")]
255
  current_item[key] = value
256
 
257
+ # print(f"Inventory Dictionary = {inventory}")
258
 
259
  if current_item:
260
  inventory[current_category].append(current_item)
utilities.py CHANGED
@@ -4,7 +4,6 @@ import os
4
  import gc
5
  import torch
6
 
7
-
8
  # Utility scripts for all modules
9
 
10
  # List for file locations to point at
@@ -36,7 +35,6 @@ def reclaim_mem():
36
  print(f"Memory Allocated after del {mem_alloc}")
37
  print(f"Memory Cached after del {mem_cache}")
38
 
39
-
40
  def generate_datetime():
41
  now = datetime.now()
42
  date_time = now.strftime("%m/%d/%Y, %H:%M:%S")
@@ -59,7 +57,6 @@ def make_image_name(name):
59
  image_name_list.append(image_name)
60
  print("Image name is : " + image_name_list[-1])
61
  return image_name
62
-
63
 
64
  # Create a unique time stamped file name
65
  def gen_file_name(mon_name):
 
4
  import gc
5
  import torch
6
 
 
7
  # Utility scripts for all modules
8
 
9
  # List for file locations to point at
 
35
  print(f"Memory Allocated after del {mem_alloc}")
36
  print(f"Memory Cached after del {mem_cache}")
37
 
 
38
  def generate_datetime():
39
  now = datetime.now()
40
  date_time = now.strftime("%m/%d/%Y, %H:%M:%S")
 
57
  image_name_list.append(image_name)
58
  print("Image name is : " + image_name_list[-1])
59
  return image_name
 
60
 
61
  # Create a unique time stamped file name
62
  def gen_file_name(mon_name):