Mirrored from https://github.com/LeeRoySheep/BookAlchemy.git
Synced Nov 2, 19:30 UTC
Added 2 routes to add author and to add book
Lee Roy Stevenson committed
Mar 28, 2025 at 05:08 UTC
5e37075504e103140e5cebdb37f97ca451d2d377
11 files changed
+245
.idea/.gitignore
new
+3
@@ -0,0 +1,3 @@
1
+# Default ignored files
2
+/shelf/
3
+/workspace.xml
.idea/BookAlchemy.iml
new
+10
@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.venv" />
6
+ </content>
7
+ <orderEntry type="jdk" jdkName="Python 3.12 (BookAlchemy)" jdkType="Python SDK" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+</module>
\ No newline at end of file
.idea/inspectionProfiles/profiles_settings.xml
new
+6
@@ -0,0 +1,6 @@
1
+<component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+</component>
\ No newline at end of file
.idea/modules.xml
new
+8
@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/BookAlchemy.iml" filepath="$PROJECT_DIR$/.idea/BookAlchemy.iml" />
6
+ </modules>
7
+ </component>
8
+</project>
\ No newline at end of file
.idea/vcs.xml
new
+6
@@ -0,0 +1,6 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+</project>
\ No newline at end of file
app.py
new
+121
@@ -0,0 +1,121 @@
1
+from datetime import datetime
2
+from flask import Flask, jsonify,render_template, request
3
+from flask_sqlalchemy import SQLAlchemy
4
+
5
+
6
+from data_models import db, Author, Book
7
+
8
+# Create Instance of Flask
9
+app = Flask(__name__)
10
+
11
+# Configure Database
12
+app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///data/library.sqlite"
13
+
14
+# Connect Flask to Database
15
+db.init_app(app)
16
+
17
+@app.route("/add_author", methods=["GET", "POST"])
18
+def add_author():
19
+ """
20
+ Route to add author with POST or search author/s with GET
21
+ :return:
22
+ """
23
+ if request.method == "GET":
24
+ name = request.args.get("name","")
25
+ if name:
26
+ authors = db.session.query(Author) \
27
+ .filter(Author.name.contains('%'+name+'%')) \
28
+ .all()
29
+ output = []
30
+ # Convert query results to Dictionary to return as JSON
31
+ for author in authors:
32
+ author = dict({'name': author.name, \
33
+ 'birth_date': author.birth_date.strftime('%Y-%m-%d'), \
34
+ 'date_of_death': author.date_of_death.strftime( '%Y-%m-%d') \
35
+ if author.date_of_death else None})
36
+ output.append(author)
37
+ return jsonify(output), 200
38
+ else:
39
+ return render_template("add_author.html")
40
+ ### POST ---------------------------------------------------------------
41
+ elif request.method == "POST":
42
+ name = request.form["name"]
43
+ birthdate = datetime.strptime(request.form["birthdate"], "%Y-%m-%d")
44
+ if request.form["date_of_death"]:
45
+ date_of_death = datetime.strptime(request.form["date_of_death"], "%Y-%m-%d")
46
+ author = Author(name=name, birth_date=birthdate, date_of_death=date_of_death)
47
+ else:
48
+ author = Author(name=name, birth_date=birthdate)
49
+ try:
50
+ db.session.add(author)
51
+ db.session.commit()
52
+ return render_template("add_author.html", success=True)
53
+ except Exception as e: # For Debugging and Testing catch all Exceptions
54
+ print(e)
55
+ return render_template("add_author.html", success=False)
56
+
57
+# Add Book Route ---------------------------------------------------
58
+@app.route("/add_book", methods=["GET", "POST"])
59
+def add_book():
60
+ if request.method == "GET":
61
+ title = request.args.get("title", "")
62
+ year = request.args.get("year", "")
63
+ isbn = request.args.get("isbn", "")
64
+ if title:
65
+ books = db.session.query(Book) \
66
+ .filter(Book.title.contains('%' + title + '%')) \
67
+ .all()
68
+ output = []
69
+ # Convert query results to Dictionary to return as JSON
70
+ for book in books:
71
+ book = dict({'title': book.title, \
72
+ 'year': book.publication_year})
73
+ output.append(book)
74
+ return jsonify(output), 200
75
+ elif year:
76
+ books = db.session.query(Book) \
77
+ .filter(Book.publication_year.contains('%' + year + '%')) \
78
+ .all()
79
+ output = []
80
+ # Convert query results to Dictionary to return as JSON
81
+ for book in books:
82
+ book = dict({'title': book.title, \
83
+ 'year': book.publication_year})
84
+ output.append(book)
85
+ return jsonify(output), 200
86
+ elif isbn:
87
+ books = db.session.query(Book) \
88
+ .filter(Book.isbn.contains('%' + isbn + '%')) \
89
+ .all()
90
+ output = []
91
+ # Convert query results to Dictionary to return as JSON
92
+ for book in books:
93
+ book = dict({'title': book.title, \
94
+ 'year': book.publication_year})
95
+ output.append(book)
96
+ return jsonify(output), 200
97
+ else:
98
+ return render_template("add_book.html")
99
+ ### POST ---------------------------------------------------------------
100
+ elif request.method == "POST":
101
+ title = request.form["title"]
102
+ year = request.form["year"]
103
+ isbn = request.form["isbn"] if request.form["isbn"] else None
104
+ author = request.form["author"]
105
+ try:
106
+ author_id = db.session.query(Author.id) \
107
+ .filter(Author.name.contains('%' + author + '%')) \
108
+ .one()[0]
109
+ book = Book(title=title, publication_year=year, isbn=isbn, author_id=author_id)
110
+ db.session.add(book)
111
+ db.session.commit()
112
+ return render_template("add_book.html", success=True)
113
+ except Exception as e: # For Debugging and Testing catch all Exceptions
114
+ print(e)
115
+ return render_template("add_book.html", success=False)
116
+
117
+app.run(debug=True)
118
+
119
+# Only needed to create datatables at the beginning of the project
120
+# with app.app_context():
121
+# db.create_all()
data_models.py
new
+27
@@ -0,0 +1,27 @@
1
+from flask_sqlalchemy import SQLAlchemy
2
+
3
+db = SQLAlchemy()
4
+
5
+class Author(db.Model):
6
+ __tablename__ = 'authors'
7
+ id = db.Column(db.Integer, primary_key=True, autoincrement=True)
8
+ name = db.Column(db.String(100))
9
+ birth_date = db.Column(db.Date)
10
+ date_of_death = db.Column(db.Date)
11
+
12
+ def __str__(self):
13
+ output = f'Name: {self.name}, Birth Date: {self.birth_date}'
14
+ return output
15
+
16
+
17
+class Book(db.Model):
18
+ __tablename__ = 'books'
19
+ id = db.Column(db.Integer, primary_key=True, autoincrement=True)
20
+ isbn = db.Column(db.String(13))
21
+ title = db.Column(db.String(100))
22
+ publication_year = db.Column(db.Integer)
23
+ author_id = db.Column(db.Integer, db.ForeignKey('authors.id'), nullable=False)
24
+
25
+ def __str__(self):
26
+ output = f'Title: {self.title}, Year: {self.year}'
27
+ return output
instance/data/library.sqlite
Binary files /dev/null and b/instance/data/library.sqlite differ
requirements.txt
new
+4
@@ -0,0 +1,4 @@
1
+flask
2
+flask-sqlalchemy
3
+jinja2
4
+sqlalchemy
templates/add_author.html
new
+28
@@ -0,0 +1,28 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ </head>
8
+ <body>
9
+ {% if success %}
10
+ <h2>Author added successfully!</h2>
11
+ {% elif success==False %}
12
+ <h2>Author not added, please try again!</h2>
13
+ {% endif %}
14
+ <form action="/add_author" method="POST">
15
+ <label for="name">Author Name:</label>
16
+ <input type="text" id="name" name="name" required><br><br>
17
+
18
+ <label for="birthdate">Birthdate:</label>
19
+ <input type="date" id="birthdate" name="birthdate" required><br><br>
20
+
21
+ <label for="date_of_death">Date of Death:</label>
22
+ <input type="date" id="date_of_death" name="date_of_death"><br><br>
23
+
24
+ <input type="submit" value="Add Author">
25
+ </form>
26
+
27
+ </body>
28
+</html>
\ No newline at end of file
templates/add_book.html
new
+32
@@ -0,0 +1,32 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ </head>
8
+ <body>
9
+ {% if success %}
10
+ <h2>Book added successfully!</h2>
11
+ {% elif success==False %}
12
+ <h2>Book not added, please try again!</h2>
13
+ {% endif %}
14
+ <form action="/add_book" method="POST">
15
+
16
+ <label for="isbn">ISBN:</label>
17
+ <input type="number" id="isbn" name="isbn" ><br><br>
18
+
19
+ <label for="title">Book Title:</label>
20
+ <input type="text" id="title" name="title" required><br><br>
21
+
22
+ <label for="year">Publication Year:</label>
23
+ <input type="number" id="year" name="year" required><br><br>
24
+
25
+ <label for="author">Author:</label>
26
+ <input type="text" id="author" name="author" required><br><br>
27
+
28
+ <input type="submit" value="Add Book">
29
+ </form>
30
+
31
+ </body>
32
+</html>