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.

249 lines
8.2 KiB

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