Advertisement
nidzone

pset7

May 26th, 2018
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.01 KB | None | 0 0
  1. from cs50 import SQL
  2. from flask import Flask, flash, redirect, render_template, request, session, url_for
  3. from flask_session import Session
  4. from passlib.apps import custom_app_context as pwd_context
  5. from tempfile import mkdtemp
  6.  
  7. from helpers import *
  8.  
  9. # configure application
  10. app = Flask(__name__)
  11.  
  12. # ensure responses aren't cached
  13. if app.config["DEBUG"]:
  14. @app.after_request
  15. def after_request(response):
  16. response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
  17. response.headers["Expires"] = 0
  18. response.headers["Pragma"] = "no-cache"
  19. return response
  20.  
  21. # custom filter
  22. app.jinja_env.filters["usd"] = usd
  23.  
  24. # configure session to use filesystem (instead of signed cookies)
  25. app.config["SESSION_FILE_DIR"] = mkdtemp()
  26. app.config["SESSION_PERMANENT"] = False
  27. app.config["SESSION_TYPE"] = "filesystem"
  28. Session(app)
  29.  
  30. # configure CS50 Library to use SQLite database
  31. db = SQL("sqlite:///finance.db")
  32.  
  33. @app.route("/")
  34. @login_required
  35. def index():
  36. portfolio_symbols = db.execute("SELECT shares, symbol FROM portfolio WHERE id = :id", id=session["user_id"])
  37.  
  38. total_cash = 0
  39.  
  40. for portfolio_symbol in portfolio_symbols:
  41. symbol = portfolio_symbol["symbol"]
  42. shares = portfolio_symbol["shares"]
  43. stock = lookup(symbol)
  44. total = shares * stock["price"]
  45. total_cash += total
  46. db.execute("UPDATE portfolio SET price=:price, total=:total WHERE id=:id AND symbol=:symbol", \
  47. price=usd(stock["price"]), total=usd(total), id=session["user_id"], symbol=symbol)
  48.  
  49. # uzimamo koliko ima novca
  50. updated_cash = db.execute("SELECT cash FROM users WHERE id=:id", id=session["user_id"])
  51.  
  52. # dodajemo na ukupan kes
  53. total_cash += updated_cash[0]["cash"]
  54.  
  55. updated_portfolio = db.execute("SELECT * from portfolio WHERE id=:id", id=session["user_id"])
  56.  
  57. return render_template("index.html", stocks=updated_portfolio, \
  58. cash=usd(updated_cash[0]["cash"]), total= usd(total_cash) )
  59.  
  60. @app.route("/buy", methods=["GET", "POST"])
  61. @login_required
  62. def buy():
  63. """Buy shares of stock."""
  64.  
  65. if request.method == "POST":
  66. stock = lookup(request.form.get("symbol"))
  67. if not stock:
  68. return apology("Invalid Symbol")
  69.  
  70. try:
  71. shares = int(request.form.get("shares"))
  72. if shares < 0:
  73. return apology("Shares must be positive integer")
  74. except:
  75. return apology("Shares must be positive integer")
  76.  
  77. money = db.execute("SELECT cash FROM users WHERE id = :id", \
  78. id=session["user_id"])
  79.  
  80. if not money or float(money[0]["cash"]) < stock["price"] * shares:
  81. return apology("Not enough money")
  82.  
  83. db.execute("INSERT INTO histories (symbol, shares, price, id) VALUES(:symbol, :shares, :price, :id)", \
  84. symbol=stock["symbol"], shares=shares, price=usd(stock["price"]), id=session["user_id"])
  85.  
  86. db.execute("UPDATE users SET cash = cash - :purchase WHERE id = :id", \
  87. id=session["user_id"], purchase=stock["price"] * float(shares))
  88.  
  89. user_shares = db.execute("SELECT shares FROM portfolio WHERE id = :id AND symbol=:symbol", \
  90. id=session["user_id"], symbol=stock["symbol"])
  91.  
  92. if not user_shares:
  93. db.execute("INSERT INTO portfolio (name, shares, price, total, symbol, id) VALUES(:name, :shares, :price, :total, :symbol, :id)", \
  94. name=stock["name"], shares=shares, price=usd(stock["price"]), total=usd(shares * stock["price"]), \
  95. symbol=stock["symbol"], id=session["user_id"])
  96.  
  97. else:
  98. shares_total = user_shares[0]["shares"] + shares
  99. db.execute("UPDATE portfolio SET shares=:shares WHERE id=:id AND symbol=:symbol", \
  100. shares=shares_total, id=session["user_id"], symbol=stock["symbol"])
  101.  
  102. return redirect(url_for("index"))
  103. else:
  104. return render_template("buy.html")
  105.  
  106.  
  107. @app.route("/history")
  108. @login_required
  109. def history():
  110. """Show history of transactions."""
  111. histories = db.execute("SELECT * from histories WHERE id=:id", id=session["user_id"])
  112.  
  113. return render_template("history.html", histories=histories)
  114.  
  115. @app.route("/login", methods=["GET", "POST"])
  116. def login():
  117. """Log user in."""
  118.  
  119. # forget any user_id
  120. session.clear()
  121.  
  122. # if user reached route via POST (as by submitting a form via POST)
  123. if request.method == "POST":
  124.  
  125. # ensure username was submitted
  126. if not request.form.get("username"):
  127. return apology("must provide username")
  128.  
  129. # ensure password was submitted
  130. elif not request.form.get("password"):
  131. return apology("must provide password")
  132.  
  133. # query database for username
  134. rows = db.execute("SELECT * FROM users WHERE username = :username", username=request.form.get("username"))
  135.  
  136. # ensure username exists and password is correct
  137. if len(rows) != 1 or not pwd_context.verify(request.form.get("password"), rows[0]["hash"]):
  138. return apology("invalid username and/or password")
  139.  
  140. # remember which user has logged in
  141. session["user_id"] = rows[0]["id"]
  142.  
  143. # redirect user to home page
  144. return redirect(url_for("index"))
  145.  
  146. # else if user reached route via GET (as by clicking a link or via redirect)
  147. else:
  148. return render_template("login.html")
  149.  
  150. @app.route("/logout")
  151. def logout():
  152. """Log user out."""
  153.  
  154. # forget any user_id
  155. session.clear()
  156.  
  157. # redirect user to login form
  158. return redirect(url_for("login"))
  159.  
  160. @app.route("/quote", methods=["GET", "POST"])
  161. @login_required
  162. def quote():
  163. """Get stock quote."""
  164. if request.method == "POST":
  165. rows = lookup(request.form.get("symbol"))
  166.  
  167. if not rows:
  168. return apology("Not valid symbol")
  169.  
  170. return render_template("quoted.html", stock=rows)
  171. else:
  172. return render_template("quote.html")
  173.  
  174.  
  175. @app.route("/register", methods=["GET", "POST"])
  176. def register():
  177. if request.method == "POST":
  178. # ensure username was submitted
  179. if not request.form.get("username"):
  180. return apology("must provide username")
  181.  
  182. elif not request.form.get("password"):
  183. return apology("must provide password")
  184.  
  185. elif request.form.get("password") != request.form.get("password_verify"):
  186. return apology("passwords must be same")
  187.  
  188. query = db.execute("INSERT INTO users (username, hash) VALUES(:username, :hash)", username=request.form.get("username"), \
  189. hash=pwd_context.hash(request.form.get("password")))
  190.  
  191. if not query:
  192. return apology("Username already exists")
  193.  
  194. # remember which user has logged in
  195. session["user_id"] = query
  196.  
  197. return redirect(url_for("index"))
  198. else:
  199. return render_template("register.html")
  200.  
  201. @app.route("/sell", methods=["GET", "POST"])
  202. @login_required
  203. def sell():
  204. """Sell shares of stock."""
  205. if request.method == "GET":
  206. return render_template("sell.html")
  207. else:
  208. stock = lookup(request.form.get("symbol"))
  209. if not stock:
  210. return apology("Invalid Symbol")
  211.  
  212. try:
  213. shares = int(request.form.get("shares"))
  214. if shares < 0:
  215. return apology("Shares must be positive integer")
  216. except:
  217. return apology("Shares must be positive integer")
  218.  
  219. user_shares = db.execute("SELECT shares FROM portfolio WHERE id = :id AND symbol=:symbol", \
  220. id=session["user_id"], symbol=stock["symbol"])
  221.  
  222. if not user_shares or int(user_shares[0]["shares"]) < shares:
  223. return apology("Not enough shares")
  224.  
  225. db.execute("INSERT INTO histories (symbol, shares, price, id) VALUES(:symbol, :shares, :price, :id)", \
  226. symbol=stock["symbol"], shares=-shares, price=usd(stock["price"]), id=session["user_id"])
  227.  
  228. db.execute("UPDATE users SET cash = cash + :purchase WHERE id = :id", \
  229. id=session["user_id"], \
  230. purchase=stock["price"] * float(shares))
  231.  
  232. shares_total = user_shares[0]["shares"] - shares
  233.  
  234. if shares_total == 0:
  235. db.execute("DELETE FROM portfolio \
  236. WHERE id=:id AND symbol=:symbol", \
  237. id=session["user_id"], \
  238. symbol=stock["symbol"])
  239. else:
  240. db.execute("UPDATE portfolio SET shares=:shares WHERE id=:id AND symbol=:symbol", \
  241. shares=shares_total, id=session["user_id"], symbol=stock["symbol"])
  242.  
  243. return redirect(url_for("index"))
  244.  
  245. @app.route("/change_pass", methods=["GET", "POST"])
  246. @login_required
  247. def change_pass():
  248. if request.method == "GET":
  249. return render_template("change_pass.html")
  250. else:
  251. if not request.form.get("old_pass"):
  252. return apology("must provide old password")
  253. elif not request.form.get("new_pass"):
  254. return apology("must provide new password")
  255. elif not request.form.get("password_verify"):
  256. return apology("input password again")
  257.  
  258. elif request.form.get("new_pass") != request.form.get("password_verify"):
  259. return apology("passwords must be same")
  260.  
  261. rows = db.execute("SELECT * FROM users WHERE id = :id", id=session["user_id"])
  262.  
  263. if len(rows) != 1 or not pwd_context.verify(request.form.get("old_pass"), rows[0]["hash"]):
  264. return apology("invalid old password")
  265.  
  266. query = db.execute("UPDATE users SET hash = :hash WHERE id = :id", hash=pwd_context.hash(request.form.get("new_pass")), id=session["user_id"])
  267.  
  268. return redirect(url_for("pass_changed"))
  269.  
  270. @app.route("/pass_changed", methods=["GET"])
  271. @login_required
  272. def pass_changed():
  273. return render_template("pass_changed.html")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement