Contact me to be added to this repository. Push the creations you make for D&D, and they will be displayed in a nice website. See the website for how to contribute.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
6.7 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. import sys
  2. from flask import Flask, render_template, request, redirect
  3. from items import get_items, get_worlds, get_monsters, get_new_items
  4. from dungeon import genGridDungeonB64
  5. from random import choice, sample
  6. import re
  7. import json
  8. from shutil import copyfile
  9. if sys.version_info.major < 3:
  10. # XXX OOF
  11. reload(sys)
  12. sys.setdefaultencoding('utf8')
  13. app = Flask(__name__)
  14. @app.route('/style.css')
  15. def style():
  16. return render_template('style.css')
  17. @app.route('/')
  18. def index():
  19. featureType = choice(["Item","Place","Spell"])
  20. item = choice(get_items("../"+featureType+"s/*"))
  21. links = [("marches","West Marches"),("dungeon","Dungeon Generator"),("about","About")]
  22. return render_template('index.html',featureType=featureType,featureText=item,links=links,new=get_new_items())
  23. @app.route('/search', methods=['POST'])
  24. def search():
  25. typ = request.form['type']
  26. query = request.form['inputText']
  27. print(typ + ": " + query)
  28. results = []
  29. for direct in ["../Items/*","../Places/*","../Spells/*"]:
  30. objects = get_items(direct)
  31. for (name,heads,body) in objects:
  32. if typ == "name":
  33. if query.lower() in name.lower():
  34. results.append((name,heads,body))
  35. elif typ == "rarity":
  36. if "rarity" in [h[0].lower() for h in heads]:
  37. if query.lower() in [h[1].lower() for h in heads if h[0].lower() == "rarity"]:
  38. results.append((name,heads,body))
  39. elif typ == "aura":
  40. if "aura" in [h[0].lower() for h in heads]:
  41. if query.lower() in [h[1].lower() for h in heads if "aura" in h[0].lower()][0]:
  42. results.append((name,heads,body))
  43. elif typ == "text":
  44. if query.lower() in body.lower():
  45. results.append((name,heads,body))
  46. print("Number of results: " + str(len(results)))
  47. featureType = choice(["Item","Place","Spell"])
  48. item = choice(get_items("../"+featureType+"s/*"))
  49. return render_template('index.html',featureType=featureType,featureText=item, searchResults=results,new=get_new_items())
  50. @app.route("/marches")
  51. def marches():
  52. return render_template('marches.html', worlds=get_worlds())
  53. @app.route("/marches/maps/<world>")
  54. def marchMap(world):
  55. #image_map = [("Temple of Constant Explosions",10,20,35),("Deep Gnome Workshop",50,40,20)] #(place,x,y,r)
  56. mfile = open("../Worlds/"+ world + "/map.json",'r')
  57. mData = mfile.read()
  58. image_map = [ (x['name'],x['x'],x['y'],x['r']) for x in json.loads(mData)['places']]
  59. return render_template("marchMap.html",worldname=world,imap=image_map)
  60. @app.route("/marches/worlds/<world>")
  61. def marchWorld(world):
  62. worldDir = "../Worlds/"+world + "/"
  63. #copy <worldname>.png from world.png into static
  64. copyfile(worldDir+"world.png","static/"+world+".png")
  65. #player_list = ["INVALID1","INVALID2","INVALID3"]
  66. empty = re.compile('^\s*$')
  67. pfile = open(worldDir + "players.txt",'r')
  68. pData = pfile.read().split('\n')
  69. player_list = [ x for x in pData if not empty.match(x)]
  70. pfile.close()
  71. #image_map = [(10,20,35),(50,40,20)] #("place name",x,y,r)
  72. #image_map = [("Temple of Constant Explosions",10,20,35),("Deep Gnome Workshop",50,40,20)] #(place,x,y,r)
  73. #log_list = ["Raiding Cosi"] # :: [AdventureName]
  74. log_list = json.load(open(worldDir + "log.json",'r')).keys()
  75. return render_template("marchWorld.html",worldname=world,players=player_list,logs=log_list)
  76. @app.route("/marches/worlds/<world>/<logname>")
  77. def marchLog(world,logname):
  78. print(logname)
  79. #... code
  80. #logname is title of adventure
  81. #log type is (DateString,X,Y,[(Name,Text)])
  82. worldDir = "../Worlds/"+world + "/"
  83. lookup = json.load(open(worldDir + "log.json", 'r'))
  84. logFile = open(worldDir+ "logs/" + lookup[logname],'r')
  85. logData = logFile.read().split('\n')
  86. name = logData[0].split(":")[1]
  87. date = logData[1].split(":")[1]
  88. X = logData[2].split(":")[1]
  89. Y = logData[3].split(":")[1]
  90. logs = []
  91. breakLine = re.compile("^---*$")
  92. for i in range(4,len(logData)):
  93. if len(logData[i]) == 0:
  94. continue
  95. if breakLine.match(logData[i]):
  96. char = logData[i+1]
  97. text = ""
  98. i += 1 #adjust offset in file. We are now at the player's name
  99. s = logData[i] #s will be the next line of the player's entry
  100. while len(s) > 0: #while there is more written text
  101. s = logData[i+1] #grab line of text
  102. text += "\n"+s
  103. i += 1
  104. logs.append((char,text))
  105. return render_template("marchLog.html",worldname=world,log=(name,date,X,Y,logs))
  106. def bucket_route(uri, dir, sing=None):
  107. if sing is None:
  108. sing = dir[:-1] # minus "s"
  109. path = '../' + dir + '/*'
  110. root = '/' + uri
  111. def render_bucket():
  112. return render_template('listing.html', title=dir, uri=uri, items=get_items(path))
  113. app.add_url_rule(root, 'render_' + uri, render_bucket)
  114. def random_bucket():
  115. nm = choice(get_items(path))[0]
  116. return redirect(root + '#' + nm)
  117. app.add_url_rule(root + '/random', 'random_' + uri, random_bucket)
  118. def bucket_table(amt):
  119. try:
  120. return render_template('table.html', title=sing + ' Table', items=sample(get_items(path), amt), roll=amt)
  121. except ValueError:
  122. return render_template('table.html', title='you dun goofed', error="Can't construct that table (not enough items?)")
  123. app.add_url_rule(root + '/table/<int:amt>', dir + '_table', bucket_table)
  124. bucket_route('items', 'Items')
  125. bucket_route('places', 'Places')
  126. bucket_route('characters', 'Characters')
  127. bucket_route('spells', 'Spells')
  128. bucket_route('feats', 'Feats')
  129. @app.route("/monsters")
  130. def render_monsters():
  131. return render_template('monsters.html',monsters=get_monsters())
  132. @app.route("/monsters/random")
  133. def random_monster():
  134. m = choice(get_monsters())
  135. return redirect("/monsters#"+m.name)
  136. @app.route("/dungeon")
  137. def dungeon():
  138. return render_template('dungeon.html')
  139. @app.route("/dungeonGen", methods=["POST"])
  140. def genDungeon():
  141. x = int(request.form['x'])
  142. y = int(request.form['y'])
  143. m = int(request.form['m'])
  144. s = int(request.form['s'])
  145. c = int(request.form['c'])
  146. enc = str(genGridDungeonB64(x,y,m,s,c))[2:-1]
  147. #if sys.version_info.major >= 3: #xxx oof?
  148. # enc = enc[2:-1]
  149. return render_template('image.html',data=enc)
  150. @app.route("/about")
  151. def about():
  152. return render_template('about.html')
  153. @app.route("/marches/campaign_info")
  154. def campaign_info():
  155. return render_template('campaign_info.html')
  156. @app.route("/marches/philosophy")
  157. def design_philosophy():
  158. return render_template('design.html')
  159. if __name__ == "__main__":
  160. app.run()