Guest User

Untitled

a guest
Jun 16th, 2018
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.21 KB | None | 0 0
  1. import os
  2.  
  3. from cs50 import SQL
  4. from flask import Flask, flash, redirect, render_template, request, session, url_for
  5. from flask_session import Session
  6. from tempfile import mkdtemp
  7. from werkzeug.exceptions import default_exceptions
  8. from passlib.apps import custom_app_context as pwd_context
  9. from werkzeug.security import check_password_hash, generate_password_hash
  10.  
  11. from helpers import apology, login_required, lookup, gbp
  12.  
  13. # Ensure environment variable is set
  14. if not os.environ.get("API_KEY"):
  15. raise RuntimeError("API_KEY not set")
  16.  
  17. # Configure application
  18. app = Flask(__name__)
  19.  
  20.  
  21. #api key
  22. # export API_KEY=CH6XN0H8ULI6ZE4E
  23.  
  24. # Ensure templates are auto-reloaded
  25. app.config["TEMPLATES_AUTO_RELOAD"] = True
  26.  
  27. # Ensure responses aren't cached
  28. @app.after_request
  29. def after_request(response):
  30. response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
  31. response.headers["Expires"] = 0
  32. response.headers["Pragma"] = "no-cache"
  33. return response
  34.  
  35. # Custom filter
  36. app.jinja_env.filters["gbp"] = gbp
  37.  
  38. # Configure session to use filesystem (instead of signed cookies)
  39. app.config["SESSION_FILE_DIR"] = mkdtemp()
  40. app.config["SESSION_PERMANENT"] = False
  41. app.config["SESSION_TYPE"] = "filesystem"
  42. Session(app)
  43.  
  44. # Configure CS50 Library to use SQLite database
  45. db = SQL("sqlite:///finance.db")
  46.  
  47. @app.route('/', defaults={'alt': False})
  48. @app.route('/index.html', defaults={'alt': True})
  49. @login_required
  50. def index():
  51. """Show portfolio of stocks"""
  52.  
  53. cash = db.execute("SELECT cash FROM users WHERE id = :id", id = session["user_id"])
  54. grandtotal = cash[0]["cash"]
  55.  
  56. # obtain stock info from portfolio database
  57. stocks = db.execute("SELECT symbol, quantity FROM transactions WHERE u_id = :u_id", u_id=session["user_id"])
  58.  
  59. # for every stock in the user's portfolio, assign dict key/values for use in html/jinja
  60. for stock in stocks:
  61. symbol = str(stock["symbol"])
  62. shares = int(stock["quantity"])
  63. name = ""
  64. price = ""
  65. total = ""
  66. quote = lookup(symbol)
  67. stock["name"] = quote["name"]
  68. stock["price"] = "{:.2f}".format(quote["price"])
  69. stock["total"] = "{:.2f}".format(quote["price"] * shares)
  70. stock["grandtotal"] = quote["price"] * shares
  71. grandtotal += stock["grandtotal"]
  72.  
  73. # format grandtotal to force 2 decimal places
  74. grandtotal = "{:.2f}".format(grandtotal)
  75.  
  76. # render index page with some given values
  77. return render_template("index.html", stocks = stocks, cash = cash, grandtotal = grandtotal)
  78.  
  79.  
  80. @app.route("/buy", methods=["GET", "POST"])
  81. @login_required
  82. def buy():
  83. """Buy shares of stock"""
  84.  
  85. if request.method == "POST":
  86.  
  87. # if symbol is empty return apology
  88. if not request.form.get("symbol"):
  89. return apology("enter a symbol")
  90.  
  91. # if shares is empty
  92. elif not request.form.get("shares"):
  93. return apology("enter shares")
  94.  
  95. elif not request.form.get("shares").isdigit():
  96. return apology("enter a number")
  97.  
  98. shares = int(request.form.get("shares"))
  99. symbol = lookup(request.form.get("symbol"))
  100.  
  101. money = db.execute("SELECT cash FROM users WHERE id = :id", \
  102. id=session["user_id"])
  103.  
  104. money = int(money[0]['cash'])
  105. if (shares * symbol['price']) > money:
  106. return apology("can't afford")
  107. else:
  108.  
  109. db.execute("INSERT INTO transactions (symbol, quantity, price, u_id) VALUES (:symbol, :quantity, :price, :u_id);", \
  110. symbol=symbol['symbol'], quantity=shares, price=symbol['price'], u_id=session["user_id"])
  111.  
  112. # update cash (define old_balance)
  113.  
  114. db.execute("UPDATE users SET cash=cash-:total_price WHERE id=:user_id;", total_price=shares*symbol['price'], \
  115. user_id=session["user_id"])
  116. return redirect(url_for("index"))
  117.  
  118. return apology("nearly")
  119.  
  120.  
  121. else:
  122. return render_template("buy.html")
  123.  
  124. @app.route("/history")
  125. @login_required
  126. def history():
  127. """Show history of transactions"""
  128.  
  129.  
  130. stocks = db.execute("SELECT symbol, quantity, price, date_time FROM transactions WHERE u_id=:u_id", u_id=session['user_id'])
  131.  
  132. for stock in stocks:
  133. stock['price'] = gbp(stock['price'])
  134.  
  135. return render_template("history.html", stocks=stocks)
  136.  
  137. @app.route("/login", methods=["GET", "POST"])
  138. def login():
  139. """Log user in"""
  140.  
  141. # Forget any user_id
  142. session.clear()
  143.  
  144. # User reached route via POST (as by submitting a form via POST)
  145. if request.method == "POST":
  146.  
  147. # Ensure username was submitted
  148. if not request.form.get("username"):
  149. return apology("must provide username", 403)
  150.  
  151. # Ensure password was submitted
  152. elif not request.form.get("password"):
  153. return apology("must provide password", 403)
  154.  
  155. # Query database for username
  156. rows = db.execute("SELECT * FROM users WHERE username = :username",
  157. username=request.form.get("username"))
  158.  
  159. # Ensure username exists and password is correct
  160. if len(rows) != 1 or not pwd_context.verify(request.form.get("password"), rows[0]["hash"]):
  161. return apology("invalid username and/or password", 403)
  162.  
  163. # Remember which user has logged in
  164. session["user_id"] = rows[0]["id"]
  165.  
  166. # Redirect user to home page
  167. return redirect("/")
  168.  
  169. # User reached route via GET (as by clicking a link or via redirect)
  170. else:
  171. return render_template("login.html")
  172.  
  173.  
  174. @app.route("/logout")
  175. def logout():
  176. """Log user out"""
  177.  
  178. # Forget any user_id
  179. session.clear()
  180.  
  181. # Redirect user to login form
  182. return redirect("/")
  183.  
  184.  
  185. @app.route("/quote", methods=["GET", "POST"])
  186. @login_required
  187. def quote():
  188. """Get stock quote."""
  189.  
  190. if request.method == "POST":
  191. rows = lookup(request.form.get("symbol"))
  192.  
  193. if not rows:
  194. return apology("Invalid Symbol")
  195.  
  196. return render_template("quoted.html", stock=rows)
  197. else:
  198. return render_template("quote.html")
  199.  
  200. @app.route("/register", methods=["GET", "POST"])
  201. def register():
  202. """Register user"""
  203.  
  204. if request.method == "POST":
  205. # Ensure username was submitted
  206. if not request.form.get("username"):
  207. return apology("must provide username")
  208.  
  209. elif not request.form.get("password"):
  210. return apology("must provide password")
  211.  
  212. elif request.form.get("confirmation") != request.form.get("password"):
  213. return apology("passwords don't match")
  214.  
  215. password = request.form.get("password")
  216. hash = pwd_context.hash(password)
  217.  
  218. result = db.execute("INSERT INTO users (username, hash) VALUES(:username, :hash)", username=request.form.get("username"), hash=hash)
  219. if not result:
  220. return apology("username exists")
  221.  
  222. user_id = db.execute("SELECT id FROM users WHERE username = :username",\
  223. username=request.form.get("username"))
  224. session['user_id'] = user_id[0]['id']
  225. return render_template("index.html")
  226.  
  227. else:
  228. return render_template("register.html")
  229.  
  230.  
  231. @app.route("/sell", methods=["GET", "POST"])
  232. @login_required
  233. def sell():
  234.  
  235. if request.method == "POST":
  236.  
  237. # if symbol is empty return apology
  238. if not request.form.get("symbol"):
  239. return apology("enter a symbol")
  240.  
  241. # if shares is empty
  242. elif not request.form.get("shares"):
  243. return apology("enter shares")
  244.  
  245. elif not request.form.get("shares").isdigit():
  246. return apology("enter a number")
  247.  
  248. shares = int(request.form.get("shares"))
  249. symbol = lookup(request.form.get("symbol"))
  250.  
  251. checkstock = db.execute("SELECT SUM(quantity) FROM transactions WHERE u_id = :u_id AND symbol = :symbol", u_id=session["user_id"], symbol=symbol["symbol"])
  252. if not checkstock[0]['SUM(quantity)']:
  253. return apology("you don't own this")
  254.  
  255.  
  256. if shares > checkstock[0]['SUM(quantity)']:
  257. return apology("you don't own that many stocks")
  258.  
  259. db.execute("INSERT INTO transactions (symbol, quantity, price, u_id) VALUES (:symbol, :quantity, :price, :u_id);", \
  260. symbol=symbol['symbol'], quantity=-shares, price=symbol['price'], u_id=session["user_id"])
  261.  
  262. # update cash
  263. db.execute("UPDATE users SET cash = cash + :total_price WHERE id = :user_id;", total_price=shares*symbol['price'], \
  264. user_id=session["user_id"])
  265. return redirect(url_for('index'))
  266.  
  267. else:
  268. return render_template("sell.html")
  269.  
  270. @app.route("/freemoney", methods=["GET", "POST"])
  271. def freemoney():
  272.  
  273. if request.method == "POST":
  274.  
  275. try:
  276. freemoney = int(request.form.get("freemoney"))
  277. if not request.form.get("freemoney"):
  278. return apology("Do you want money or not?")
  279. elif freemoney > 1000:
  280. return apology("Not that much, sorry")
  281. except:
  282. return apology("Not that much, sorry")
  283.  
  284. db.execute("UPDATE users SET cash = cash + :freemoney WHERE id = :id", freemoney=freemoney, id=session["user_id"])
  285.  
  286. return render_template("buy.html")
  287.  
  288. else:
  289. return render_template("freemoney.html")
  290.  
  291.  
  292. def errorhandler(e):
  293. """Handle error"""
  294. return apology(e.name, e.code)
  295.  
  296.  
  297. # listen for errors
  298. for code in default_exceptions:
  299. app.errorhandler(code)(errorhandler)
Add Comment
Please, Sign In to add comment