Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 65182ff

Browse files
committed
Adding project1 - Books to the repository
1 parent 01d226e commit 65182ff

26 files changed

+5522
-0
lines changed
549 Bytes
Binary file not shown.

‎lecture2/application.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from flask import Flask, render_template
2+
3+
app = Flask(__name__)
4+
5+
@app.route("/")
6+
def index():
7+
return render_template("index.html")
8+
9+
@app.route("/<string:name>")
10+
def hello(name):
11+
name = name.capitalize()
12+
return f"<h1>Hello, {name}!</h1>"

‎lecture2/templates/index.html‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% extends "layout.html" %}
2+
3+
{% block title %}
4+
Index
5+
{% endblock %}
6+
7+
{% block body %}
8+
9+
<h2>Index.html</h2>
10+
11+
{% endblock %}

‎lecture2/templates/layout.html‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>{% block title %} {% endblock %}</title>
5+
</head>
6+
<body>
7+
<h1>Hello World</h1>
8+
{% block body %} {% endblock %}
9+
</body>
10+
</html>

‎lecture3/create.sql‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE flights (
2+
id SERIAL PRIMARY KEY,
3+
origin VARCHAR NOT NULL,
4+
destination VARCHAR NOT NULL,
5+
duration INTEGER NOT NULL
6+
);

‎project1/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Project 1
2+
3+
Web Programming with Python and JavaScript
5.58 KB
Binary file not shown.
974 Bytes
Binary file not shown.

‎project1/application.py‎

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import os
2+
3+
import json
4+
5+
from flask import Flask, session, render_template, request, jsonify
6+
from flask_session import Session
7+
from sqlalchemy import create_engine
8+
from sqlalchemy.orm import scoped_session, sessionmaker
9+
10+
from classes import User, Book
11+
12+
import requests
13+
14+
app = Flask(__name__)
15+
16+
# Check for environment variable
17+
if not os.getenv("DATABASE_URL"):
18+
raise RuntimeError("DATABASE_URL is not set")
19+
20+
# Configure session to use filesystem
21+
app.config["SESSION_PERMANENT"] = False
22+
app.config["SESSION_TYPE"] = "filesystem"
23+
Session(app)
24+
25+
# Set up database
26+
engine = create_engine(os.getenv("DATABASE_URL"))
27+
db = scoped_session(sessionmaker(bind=engine))
28+
29+
30+
@app.route("/")
31+
def index():
32+
if session["user"] is None:
33+
return login()
34+
else:
35+
return render_template("index.html")
36+
37+
38+
@app.route("/login", methods=["GET", "POST"])
39+
def login():
40+
41+
if request.method == "POST":
42+
43+
username = request.form.get("username")
44+
password = request.form.get("password")
45+
result = db.execute("SELECT id, name, email, username, password FROM users WHERE username=:username AND password=:password", {"username": username, "password": password}).fetchone()
46+
if result is None:
47+
return render_template("error.html", message="Username or password incorrect")
48+
else:
49+
user = User(result.id, result.name, result.email, result.username, result.password)
50+
51+
52+
if user:
53+
session["user"] = user
54+
return render_template("index.html")
55+
56+
return render_template("login.html")
57+
58+
59+
@app.route("/register", methods=["GET", "POST"])
60+
def register():
61+
if request.method == 'GET':
62+
return render_template("register.html")
63+
else:
64+
name = request.form.get("name")
65+
username = request.form.get("username")
66+
email = request.form.get("email")
67+
password = request.form.get("password")
68+
db.execute("INSERT INTO users(name, email, username, password) VALUES (:name, :email, :username, :password)", {"name": name, "email": email, "username": username, "password": password})
69+
db.commit()
70+
return render_template("login.html")
71+
72+
73+
@app.route("/layout")
74+
def layout():
75+
return render_template("layout.html")
76+
77+
78+
@app.route("/logout")
79+
def logout():
80+
""" Logout the user and clean the cache session"""
81+
session["user"] = None
82+
return render_template("login.html")
83+
84+
85+
@app.route("/books", methods=["GET", "POST"])
86+
def books():
87+
if session["user"] is None:
88+
return login()
89+
90+
""" If the request is GET, render the page of search to the user with no books"""
91+
if request.method == "GET":
92+
return render_template("books.html")
93+
else:
94+
""" If the request is POST, do the search with the text provided by the user"""
95+
text = "%"+request.form.get("search-text")+"%"
96+
books = db.execute("SELECT * FROM books WHERE (isbn LIKE :isbn OR title LIKE :title OR author LIKE :author OR year LIKE :year)", {"isbn":text, "title":text, "author":text, "year":text}).fetchall()
97+
return render_template("books.html", books=books)
98+
99+
100+
@app.route("/details/<string:isbn>", methods=["GET", "POST"])
101+
def details(isbn):
102+
if session["user"] is None:
103+
return login()
104+
""" Give all the details about the book"""
105+
book = Book()
106+
107+
book.isbn, book.title, book.author, book.year, book.reviews_count, book.average_rating = db.execute("SELECT isbn, title, author, year, reviews_count, average_rating FROM books WHERE isbn = :isbn", {"isbn": isbn}).fetchone()
108+
109+
if book.average_rating==0 or book.reviews_count==0:
110+
book_aux = api_intern(isbn)
111+
112+
book.average_rating = book_aux["books"][0]["average_rating"]
113+
book.reviews_count = book_aux["books"][0]["reviews_count"]
114+
db.execute("UPDATE books SET average_rating = :average_rating, reviews_count = :reviews_count WHERE isbn=:isbn", {"isbn": isbn, "average_rating": float(book.average_rating), "reviews_count": int(book.reviews_count)})
115+
116+
db.commit()
117+
if request.method == "GET":
118+
return render_template("details.html", book=book)
119+
else:
120+
return "POST DETAILS"
121+
122+
123+
@app.route("/api/<string:isbn>", methods=["GET"])
124+
def api(isbn):
125+
""" Give all the details about the book"""
126+
if request.method == "GET":
127+
res = db.execute("SELECT title, author, year, isbn, reviews_count, average_rating FROM books WHERE isbn = :isbn", {"isbn": isbn}).fetchone()
128+
book = Book()
129+
130+
if res is None:
131+
return render_template("error.html", message="404 book not found"), 404
132+
133+
book.title, book.author, book.year, book.isbn, book.reviews_count, book.average_rating = res
134+
if res.reviews_count==0 or res.average_rating==0:
135+
book_aux = api_intern(isbn)
136+
book.average_rating = book_aux["books"][0]["average_rating"]
137+
book.reviews_count = book_aux["books"][0]["reviews_count"]
138+
139+
response = {"title": book.title, "author": book.author, "year": book.year, "isbn": book.isbn, "review_count": book.reviews_count, "average_score": book.average_rating}
140+
return jsonify(response)
141+
142+
143+
def api_intern(isbn):
144+
""" Give all the details about the book"""
145+
res = requests.get("https://www.goodreads.com/book/review_counts.json", params={"key": "tG3fNOMnNgw8HsbsI1Rhdg", "isbns": isbn})
146+
147+
return res.json()
148+
149+
150+
""" Route to submit and see the reviews from one book"""
151+
@app.route("/review/<string:isbn>", methods=["GET", "POST"])
152+
def review(isbn):
153+
if session["user"] is None:
154+
return login()
155+
156+
""" Render form to the user submit a review """
157+
book = db.execute("SELECT * FROM books WHERE isbn= :isbn"
158+
, {"isbn": isbn}).fetchone()
159+
if request.method == "POST":
160+
review = request.form.get("review")
161+
score = request.form.get("score")
162+
""" Calculating new average rating and number of reviews from the book """
163+
average_rating = (book.average_rating + float(score))/2
164+
reviews_count = book.reviews_count + 1
165+
comments = db.execute("SELECT * FROM reviews WHERE author_id= :author_id AND book_isbn= :book_isbn", {"author_id": session["user"].id, "book_isbn": isbn}).fetchone()
166+
167+
""" Checks if the user already made a comment to this book """
168+
if comments is not None:
169+
return render_template("error.html", message="You already posted a comment to this book")
170+
171+
db.execute("INSERT INTO reviews(review, score, author_id, book_isbn) VALUES (:review, :score, :author_id, :book_isbn)", {"review": review, "score": score, "author_id": session["user"].id, "book_isbn": isbn})
172+
db.execute("UPDATE books SET average_rating = :average_rating, reviews_count = :reviews_count WHERE isbn=:isbn", {"isbn": isbn, "average_rating": average_rating, "reviews_count": reviews_count})
173+
174+
db.commit()
175+
176+
reviews = db.execute("SELECT * FROM reviews WHERE book_isbn= :isbn"
177+
, {"isbn": isbn}).fetchall()
178+
return render_template("review.html", book=book, reviews=reviews)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /