-
Notifications
You must be signed in to change notification settings - Fork 0
/
enter.py
337 lines (293 loc) · 10.1 KB
/
enter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
import json
import os
import dndice
from classes.colors import Colors
from classes.entity import Entity
from classes.entity import EntityNotFoundError
from classes.entity import EntityAlreadyExistsError
from classes.context import Context
from classes.context import ContextEntityConflictError
from classes.custom.place.multiverse import Multiverse
from classes.spec import Spec
from classes.spec import InvalidSpecStringError
# Config
basePath = "reality/"
multiverseKey = "existence"
terminalHeight = 80 # 80 is full screen
historyFile = "history.json";
# Functions for this wrapper...
def nth_repl_all(s, sub, repl, nth):
find = s.find(sub)
# loop util we find no match
i = 1
while find != -1:
# if i is equal to nth we found nth matches so replace
if i == nth:
s = s[:find]+repl+s[find + len(sub):]
i = 0
# find + len(sub) + 1 means we start after the last match
find = s.find(sub, find + len(sub) + 1)
i += 1
return s
def myPrint(txt):
print(txt)
def myPrompt(txt):
return input(txt)
def stringToSpec(s):
return Spec.getSpecFromString(s)
def specToString(s):
return Spec.getStringFromSpec(s)
def getSpacer():
return "\n--\n"
def clearScreen():
for i in range (0, terminalHeight):
myPrint("")
def printActionText(str):
for i in range (0, 2):
myPrint("")
myPrint(Colors.HEADER+"###### ## # "+str+" # # #################### #### ### ## # #"+Colors.ENDC)
def show(entity):
clearScreen()
printActionText(entity.name+" ("+entity.key+")"+" <"+entity.spec.name.upper()+">")
printContextStack()
myPrint("")
myPrint(entity.toString())
# spacer = getSpacer()
# myPrint(spacer)
def printContextStack():
s = ""
first = True
for context in reversed(contextStack):
if (not first):
s += " <- "
s += Colors.OKCYAN+(context.name or "Unnamed")+Colors.ENDC+Colors.OKGREEN+" <"+context.spec.name.upper()+">"+Colors.ENDC
first = False
myPrint(s)
def update(entity):
entity.update()
def delete(entity):
entity.delete()
def saveHistory(historyList):
with open(historyFile, 'w') as file:
file.write(json.dumps(historyList))
def coalesce(*arg):
return reduce(lambda x, y: x if x is not None else y, arg)
def codex(filename):
filename = filename.lower()
for root, dirs, files in os.walk('codex'):
for file in files:
if file == (filename+'.md'):
f = open(root+"\\"+file)
codexEntryText = f.read()
f.close()
codexEntryText = nth_repl_all(codexEntryText, "**", Colors.ENDC, 2)
codexEntryText = nth_repl_all(codexEntryText, "**", Colors.BOLD, 1)
codexEntryText = nth_repl_all(codexEntryText, "##", Colors.ENDC, 2)
codexEntryText = nth_repl_all(codexEntryText, "##", Colors.WARNING, 1)
clearScreen()
myPrint(Colors.HEADER+"######## ### ## # "+file.split('.')[0].upper()+" # ## ### ####### ## # #"+Colors.ENDC)
myPrint("")
myPrint(codexEntryText)
myPrint("")
return
raise CodexEntryNotFoundError
def listCodex():
myPrint("Usage: codex [filename]. You can view the following entries:")
first = True
for root, dirs, files in os.walk('codex'):
if first:
first = False
continue
myPrint("Category: "+root.split('\\')[1].upper())
for file in files:
myPrint(" * " + file.split('.')[0].upper())
# Errors for this wrapper...
class EntityIsNotAContextError(Exception):
pass
class CodexEntryNotFoundError(Exception):
pass
# Create the context stack, for browsing reality
contextStack = []
# Attempt to load the root of reality... (multiverse)
clearScreen()
try:
myPrint(Colors.WARNING+"Attempting to load a multiverse with key ("+multiverseKey+") from directory '"+basePath+"'..."+Colors.ENDC)
existence = Multiverse(multiverseKey, basePath)
existence.load()
myPrint(Colors.OKGREEN+"Success!"+Colors.ENDC)
except EntityNotFoundError:
# If it doesn't exist, create it...
myPrint(Colors.FAIL+"Nothing exists! Creating a multiverse..."+Colors.ENDC)
existence.create()
myPrint(Colors.OKGREEN+"Success!"+Colors.ENDC)
myPrint(Colors.UNDERLINE+"Type \"help\" for options!"+Colors.ENDC)
# Place the multiverse onto the context stack
contextStack.append(existence)
# if there is a history list, load it all
if os.path.isfile(historyFile):
f = open(historyFile, "r")
# print(f.read())
historyList = json.loads(f.read())
f.close()
historyList.pop() # remove existence. we know its on top from above.
historyList.reverse()
for historyKey in historyList:
contextStack.append(contextStack[-1].find(historyKey))
frameOfReference = contextStack.pop()
show(frameOfReference)
contextStack.append(frameOfReference)
# Begin main loop
# Main loop assumes that the context stack has the current context at top
# It will pull it off and perform interactions on the current context, based on user input
# Valid commands include [add [entity] [key], update [key], show [key], delete [key]], use [key]
# A user should be asked for a command each loop, and can end any time by typing 'exit'
args = [-1]
while (args[0] != "exit"):
# Pop off the current frame of reference
frameOfReference = contextStack.pop()
# Get the users choice
argument = myPrompt((Colors.OKGREEN+"(%s)"+Colors.ENDC+"> ") % (frameOfReference.getKey()))
# argument = myPrompt("> ")
if (argument == ""): # No input condition
# Re-append the current frameOfReference
contextStack.append(frameOfReference)
continue
# Split it into an array of strings
# 0 -> the original command [add, update, show, delete]
# 1 -> the entity type-string if add, the entity key otherwise (key is optional. No key passed - operate on self)
# 2 -> The entity key, if add. Not used otherwise
args = argument.split()
# Handle
# 0:add 1:entity 2:key
if (args[0] in ["add", "new"]):
if (len(args) > 2):
try:
entitySpec = stringToSpec(args[1].lower())
frameOfReference.add(args[2], entitySpec)
show(frameOfReference)
myPrint("Successfully added %s." % (args[1].lower()))
except InvalidSpecStringError:
myPrint("Entity type '%s' is unrecognized." % (args[1].lower()))
except ContextEntityConflictError:
myPrint("Entity type '%s' is unrecognized by the frame of reference." % entitySpec.name)
except EntityAlreadyExistsError:
myPrint("An entity with key '%s' already exists." % (args[2]))
else:
myPrint("Usage: add [entity] [key]. Keys are unique. The following entities are permitted here:")
for someSpec in frameOfReference.allowedChildEntities:
myPrint("* " + someSpec.name)
# 0:update 1:key
elif (args[0] in ["update", "edit"]):
if (len(args) > 1):
try:
entity = frameOfReference.find(args[1])
update(entity)
show(frameOfReference)
except EntityNotFoundError:
myPrint("No entity with the key '%s' exists in this frame of reference." % (args[1]))
else:
update(frameOfReference)
# 0:show 1:key
elif (args[0] in ["show", "ls"]):
if (len(args) > 1):
if args[1] == "..":
if (len(contextStack) >= 1):
show(contextStack[-1])
else:
myPrint("Cannot show outside the multiverse.")
else:
try:
show(frameOfReference.find(args[1]))
except EntityNotFoundError:
myPrint("No entity with the key '%s' exists in this frame of reference." % (args[1]))
else:
show(frameOfReference)
# 0:delete 1:key
elif (args[0] in ["delete", "rm"]):
if (len(args) > 1):
try:
entity = frameOfReference.find(args[1])
delete(entity)
show(frameOfReference)
except EntityNotFoundError:
myPrint("No entity with the key '%s' exists in this frame of reference." % (args[1]))
else:
if (len(contextStack) >= 1):
entityToDelete = frameOfReference
frameOfReference = contextStack.pop()
delete(entityToDelete)
show(frameOfReference)
else:
myPrint("Cannot delete the multiverse.")
# 0:use 1:key
elif (args[0] in ["use", "cd"]):
if (len(args) > 1):
if args[1] == "..": # copy paste from back: logic
if (len(contextStack) >= 1):
frameOfReference = contextStack.pop()
show(frameOfReference)
else:
myPrint("Cannot move outside the multiverse.")
else:
try:
context = frameOfReference.find(args[1])
if (not context.getIsContext()):
raise EntityIsNotAContextError("Attempted to use entity as a context, when it is not.")
contextStack.append(frameOfReference)
frameOfReference = context
show(frameOfReference)
except EntityNotFoundError:
myPrint("No entity with the key '%s' exists in this frame of reference." % (args[1]))
except EntityIsNotAContextError:
myPrint("'%s' is not a contextual entity and cannot be used." % (args[1]))
else:
myPrint("Usage: use [key]. Keys are unique.")
# 0:show 1:file
elif (args[0] in ["codex", "x"]):
if (len(args) > 1):
try:
codex(args[1])
except CodexEntryNotFoundError:
myPrint("No codex entry with the file name '%s' exists." % (args[1]))
else:
listCodex()
elif (args[0] in ["r", "roll"]):
if (len(args) > 1):
if args[1].startswith('d'):
result = dndice.verbose('1'+args[1])
else:
result = dndice.verbose(args[1])
myPrint(result)
else:
myPrint("Usage: roll [#d#+#]")
# 0:back
elif (args[0] == "back"):
if (len(contextStack) >= 1):
frameOfReference = contextStack.pop()
show(frameOfReference)
else:
myPrint("Cannot move outside the multiverse.")
# 0:help
elif (args[0] == "help"):
myPrint("Commands: ")
myPrint(" add [entity] [key] Add a new entity to the current frame of reference")
myPrint(" update [?key] Key optional. Update the entity")
myPrint(" ls [?key] Key optional. Show the entity")
myPrint(" delete [?key] Key optional. Delete the entity")
myPrint(" cd [key] Attempt to use the given entity as the current frame of reference")
myPrint(" codex [file] Read a codex entry.")
myPrint(" roll [#d#+#] Roll some dice")
myPrint(" back Move back a context on the stack")
myPrint(" exit Save and quit.")
# 0:exit
elif (args[0] == "exit"):
myPrint("Exiting...")
keyHistory = [frameOfReference.key]
while contextStack:
keyHistory.append(contextStack.pop().key)
saveHistory(keyHistory);
# 0:???
else:
myPrint("Operation not recognized. Try 'help'")
# Re-append the current frameOfReference
contextStack.append(frameOfReference)