-
Notifications
You must be signed in to change notification settings - Fork 0
/
application.py
159 lines (137 loc) · 5.83 KB
/
application.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
from cs50 import SQL
from flask import Flask, flash, redirect, render_template, request, url_for, send_from_directory, session
from flask_session import Session
from tempfile import mkdtemp
import os
import sqlalchemy
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions
from werkzeug.utils import secure_filename
from random import randint
import capitalizeIt
import urlparse
import psycopg2
urlparse.uses_netloc.append("postgres")
url = urlparse.urlparse(os.environ["DATABASE_URL"])
conn = psycopg2.connect(
database=url.path[1:],
user=url.username,
password=url.password,
host=url.hostname,
port=url.port
)
ALLOWED_EXTENSIONS = set(["txt"])
UPLOAD_FOLDER = "./uploads"
# Configure application
app = Flask(__name__)
app.secret_key = "dsfgsdHUIg97btb8632FD"
# Max file upload size
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024
# Path for uploaded files to be temporarily saved
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Configure CS50 Library to use SQLite database
db = SQL(os.environ["DATABASE_URL"])
# Ensure responses aren't cached
@app.after_request
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
@app.route("/", methods=["GET", "POST"])
def index():
"""Home"""
if request.method == "POST":
# user requested to capitalize text
if request.form.get("submit") == "capitalize" and request.form.get("text"):
# on the first request, ask user to rate
if "id" not in session:
flash("Please take a moment to rate the accuracy of your request below.", "primary")
session["id"]=randint(0,1000000)
return render_template("capitalized.html", new_text=capitalizeIt.cap(request.form.get("text")),
old_text=request.form.get("text"))
# user requested to upload file
elif request.form.get("submit") == "upload":
return redirect("/uploader")
# user submitted rating
elif request.form.get("rating"):
db.execute("INSERT INTO ratings (rating) VALUES (:rating)", rating=request.form.get("rating"))
flash("Thanks for rating!", "primary")
return render_template("capitalized.html", new_text=capitalizeIt.cap(request.form.get("text")),
old_text=request.form.get("text"))
return render_template("index.html")
# function for checking if file is allowed format (from Flask documentation)
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route("/uploader", methods=["GET", "POST"])
def uploader():
"""Uplading and reading files"""
if request.method == "POST":
# check if the post request has the file part
if "file" not in request.files:
flash("No file part", "danger")
return redirect(request.url)
file = request.files["file"]
# check that user selected file
if not file.filename:
flash("No selected file", "danger")
return redirect(request.url)
if file:
# check that user submitted valid file format
if not allowed_file(file.filename):
flash("Invalid file format", "danger")
return redirect(request.url)
# save file with secure_filename to sanitize user input and attach random number to avoid file name duplications, then read file contents
filename = secure_filename(file.filename).split(".")[0] + str(randint(0,1000000)) + ".txt"
file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
fileObj = open(os.path.join(app.config["UPLOAD_FOLDER"], filename), "r")
text = fileObj.read()
# close and delete file
fileObj.close()
os.remove(os.path.join(app.config["UPLOAD_FOLDER"], filename))
# capitalize file contents and on the first request, ask user to rate
if "id" not in session:
flash("Please take a moment to rate the accuracy of your request below.", "primary")
session["id"]=randint(0,1000000)
return render_template("capitalized.html", new_text=capitalizeIt.cap(text),
old_text=text)
return render_template("uploader.html")
def errorhandler(e):
"""Show error"""
return render_template("error.html", eName=e.name, eCode=e.code)
# listen for errors
for code in default_exceptions:
app.errorhandler(code)(errorhandler)
class SQL(object):
def __init__(self, url):
try:
self.engine = sqlalchemy.create_engine(url)
except Exception as e:
raise RuntimeError(e)
def execute(self, text, *multiparams, **params):
try:
statement = sqlalchemy.text(text).bindparams(*multiparams, **params)
result = self.engine.execute(str(statement.compile(compile_kwargs={"literal_binds": True})))
# SELECT
if result.returns_rows:
rows = result.fetchall()
return [dict(row) for row in rows]
# INSERT
elif result.lastrowid is not None:
return result.lastrowid
# DELETE, UPDATE
else:
return result.rowcount
except sqlalchemy.exc.IntegrityError:
return None
except Exception as e:
raise RuntimeError(e)
if __name__ == "__main__":
app.debug = True
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port)