├── .gitignore
├── database.db
├── static
├── images
│ ├── logo.png
│ └── shoppingCart.png
├── uploads
│ ├── storediagram.gif
│ ├── WWW.YIFY-TORRENTS.COM.jpg
│ ├── Untitled_by_Aaron_Burden.jpg
│ ├── Untitled_by_Troy_Jarrell.jpg
│ ├── Untitled_0026_by_Mike_Sinko.jpg
│ ├── Untitled_7019_by_Mike_Sinko.jpg
│ ├── Yellow_Jacket_by_Manuel_Frei.png
│ ├── Kinkaku_Ji_by_Elizabeth_K_Joseph.jpg
│ ├── Mountainous_View_by_Sven_Scheuermeier.jpg
│ ├── The_Sky_Is_The_Limit_by_Kaushik_Panchal.jpg
│ └── 17068-purple-planet-1366x768-fantasy-wallpaper.png
├── css
│ ├── remove.css
│ ├── home.css
│ ├── productDescription.css
│ ├── cart.css
│ └── topStyle.css
└── js
│ ├── changePassword.js
│ └── validateForm.js
├── Pipfile
├── templates
├── login.html
├── remove.html
├── add.html
├── changePassword.html
├── register.html
├── profileHome.html
├── cart.html
├── displayCategory.html
├── productDescription.html
├── home.html
└── editProfile.html
├── README.md
├── database.py
├── LICENSE
├── Pipfile.lock
└── main.py
/.gitignore:
--------------------------------------------------------------------------------
1 | query.py
2 |
--------------------------------------------------------------------------------
/database.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/database.db
--------------------------------------------------------------------------------
/static/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/images/logo.png
--------------------------------------------------------------------------------
/static/images/shoppingCart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/images/shoppingCart.png
--------------------------------------------------------------------------------
/static/uploads/storediagram.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/storediagram.gif
--------------------------------------------------------------------------------
/static/css/remove.css:
--------------------------------------------------------------------------------
1 | table {
2 | border-width: 10px;
3 | }
4 |
5 | #itemImage {
6 | height: 100px;
7 | width: 80px;
8 | }
9 |
--------------------------------------------------------------------------------
/static/uploads/WWW.YIFY-TORRENTS.COM.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/WWW.YIFY-TORRENTS.COM.jpg
--------------------------------------------------------------------------------
/static/uploads/Untitled_by_Aaron_Burden.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Untitled_by_Aaron_Burden.jpg
--------------------------------------------------------------------------------
/static/uploads/Untitled_by_Troy_Jarrell.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Untitled_by_Troy_Jarrell.jpg
--------------------------------------------------------------------------------
/static/uploads/Untitled_0026_by_Mike_Sinko.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Untitled_0026_by_Mike_Sinko.jpg
--------------------------------------------------------------------------------
/static/uploads/Untitled_7019_by_Mike_Sinko.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Untitled_7019_by_Mike_Sinko.jpg
--------------------------------------------------------------------------------
/static/uploads/Yellow_Jacket_by_Manuel_Frei.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Yellow_Jacket_by_Manuel_Frei.png
--------------------------------------------------------------------------------
/static/uploads/Kinkaku_Ji_by_Elizabeth_K_Joseph.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Kinkaku_Ji_by_Elizabeth_K_Joseph.jpg
--------------------------------------------------------------------------------
/static/uploads/Mountainous_View_by_Sven_Scheuermeier.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/Mountainous_View_by_Sven_Scheuermeier.jpg
--------------------------------------------------------------------------------
/static/uploads/The_Sky_Is_The_Limit_by_Kaushik_Panchal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/The_Sky_Is_The_Limit_by_Kaushik_Panchal.jpg
--------------------------------------------------------------------------------
/static/uploads/17068-purple-planet-1366x768-fantasy-wallpaper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HarshShah1997/Shopping-Cart/HEAD/static/uploads/17068-purple-planet-1366x768-fantasy-wallpaper.png
--------------------------------------------------------------------------------
/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 | url = "https://pypi.org/simple"
3 | verify_ssl = true
4 | name = "pypi"
5 |
6 | [packages]
7 | flask = "*"
8 | pysqlite3 = "*"
9 |
10 | [dev-packages]
11 |
12 | [requires]
13 | python_version = "3.8"
14 |
--------------------------------------------------------------------------------
/static/js/changePassword.js:
--------------------------------------------------------------------------------
1 | function validate() {
2 | var pass = document.getElementById("newpassword").value;
3 | var cpass = document.getElementById("cpassword").value;
4 | if (pass == cpass) {
5 | return true;
6 | } else {
7 | alert("Passwords do not match!");
8 | return false;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/static/js/validateForm.js:
--------------------------------------------------------------------------------
1 | function validate() {
2 | var pass = document.getElementById("password").value;
3 | var cpass = document.getElementById("cpassword").value;
4 | if (pass == cpass) {
5 | return true;
6 | } else {
7 | alert("Passwords do not match");
8 | return false;
9 | }
10 | }
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | First flask app
4 |
5 |
6 | {{error}}
7 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/static/css/home.css:
--------------------------------------------------------------------------------
1 |
2 | #itemImage {
3 | height: 200px;
4 | width: 150px;
5 | }
6 |
7 | .display {
8 | margin-top: 20px;
9 | margin-left: 20px;
10 | margin-right: 20px;
11 | margin-bottom: 20px;
12 | }
13 |
14 | table {
15 | border-spacing: 20px;
16 | }
17 |
18 | #productName {
19 | text-align: center;
20 | font-weight: bold;
21 | }
22 |
23 | #productPrice {
24 | text-align: center;
25 | }
26 |
27 | .displayCategory ul li {
28 | font-size: 20px;
29 | }
30 |
--------------------------------------------------------------------------------
/templates/remove.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Remove
5 |
6 |
7 |
8 |
9 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/static/css/productDescription.css:
--------------------------------------------------------------------------------
1 | #display {
2 | margin-top: 20px;
3 | margin-left: 20px;
4 | margin-right: 20px;
5 | margin-bottom: 20px;
6 | }
7 |
8 | #productImage {
9 | height: 250px;
10 | width: 200px;
11 | margin-left: 20px;
12 | margin-right: 20px;
13 | margin-top: 20px;
14 | margin-bottom: 20px;
15 | display: inline-block;
16 | float: left;
17 | }
18 |
19 | #productDescription {
20 | margin-left: 20px;
21 | margin-right: 20px;
22 | margin-top: 20px;
23 | margin-bottom: 20px;
24 | display: inline-block;
25 | font-size: 19px;
26 | }
27 |
28 | #descriptionTable td {
29 | width: 150px;
30 | }
31 |
32 | #addToCart {
33 | font-size: 20px;
34 | }
35 |
36 |
37 |
--------------------------------------------------------------------------------
/templates/add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Admin
5 |
6 |
7 | Add items
8 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/templates/changePassword.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Change Password
4 |
5 |
6 |
7 | Change password
8 | {{ msg }}
9 |
15 | Go to Profile
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Shopping Cart
2 | A simple E-commerce website using Flask.
3 |
4 | ## Dependencies ##
5 | 1. Python3
6 | 2. Flask
7 | 3. Sqlite
8 |
9 | ## How to run ##
10 | 1. Set up database by running database.py (Or you can reuse existing database included in the repo)
11 | 2. Run main.py
12 | 3. Enter localhost:5000 in the browser
13 |
14 | ## Pipenv instructions ##
15 | 1. Install pipenv (python3 -m pip install --user pipenv)
16 | 2. Install dependencies (pipenv install --dev)
17 | 3. Setup database (pipenv run python database.py)
18 | 4. Run the server (pipenv run python main.py)
19 | 5. Enter localhost:5000 in the browser
20 |
21 | ## Sample User ##
22 | Sample credentials present in existing database:
23 | Username - sample@example.com
24 | Password - sample
25 |
26 |
--------------------------------------------------------------------------------
/database.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 |
3 | #Open database
4 | conn = sqlite3.connect('database.db')
5 |
6 | #Create table
7 | conn.execute('''CREATE TABLE users
8 | (userId INTEGER PRIMARY KEY,
9 | password TEXT,
10 | email TEXT,
11 | firstName TEXT,
12 | lastName TEXT,
13 | address1 TEXT,
14 | address2 TEXT,
15 | zipcode TEXT,
16 | city TEXT,
17 | state TEXT,
18 | country TEXT,
19 | phone TEXT
20 | )''')
21 |
22 | conn.execute('''CREATE TABLE products
23 | (productId INTEGER PRIMARY KEY,
24 | name TEXT,
25 | price REAL,
26 | description TEXT,
27 | image TEXT,
28 | stock INTEGER,
29 | categoryId INTEGER,
30 | FOREIGN KEY(categoryId) REFERENCES categories(categoryId)
31 | )''')
32 |
33 | conn.execute('''CREATE TABLE kart
34 | (userId INTEGER,
35 | productId INTEGER,
36 | FOREIGN KEY(userId) REFERENCES users(userId),
37 | FOREIGN KEY(productId) REFERENCES products(productId)
38 | )''')
39 |
40 | conn.execute('''CREATE TABLE categories
41 | (categoryId INTEGER PRIMARY KEY,
42 | name TEXT
43 | )''')
44 |
45 |
46 |
47 | conn.close()
48 |
49 |
--------------------------------------------------------------------------------
/static/css/cart.css:
--------------------------------------------------------------------------------
1 | #tableItems {
2 | margin-left: 20px;
3 | margin-right: 20px;
4 | margin-top: 20px;
5 | margin-bottom: 20px;
6 | }
7 |
8 | #itemImage {
9 | margin-left: 5px;
10 | margin-right: 5px;
11 | margin-top: 5px;
12 | margin-bottom: 5px;
13 | height: 100px;
14 | float: left;
15 | }
16 |
17 | #itemName {
18 | margin-left: 5px;
19 | margin-right: 5px;
20 | margin-top: 5px;
21 | margin-bottom: 5px;
22 | height: 100px;
23 | width: 200px;
24 | float: left;
25 | }
26 |
27 | #titleName {
28 | width: 200px;
29 | float: left;
30 | }
31 |
32 | #titlePrice {
33 | float: left;
34 | }
35 |
36 | #itemPrice {
37 | margin-left: 5px;
38 | margin-right: 5px;
39 | margin-top: 5px;
40 | margin-bottom: 5px;
41 | height: 100px;
42 | display: inline-block;
43 | }
44 |
45 | #image {
46 | height: 100px;
47 | width: 80px;
48 | }
49 |
50 | #seperator {
51 | margin: 0px;
52 | max-width: 400px;
53 | }
54 |
55 | #total {
56 | padding-left: 280px;
57 | }
58 |
59 | #itemNameTag {
60 | font-weight: bold;
61 | }
62 |
63 | #subtotal {
64 | font-weight: bold;
65 | font-size: 20px;
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Harsh Shah
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/templates/register.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Registration
4 |
6 |
7 |
8 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/templates/profileHome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Profile Home
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/static/css/topStyle.css:
--------------------------------------------------------------------------------
1 | #logo {
2 | height: 40px;
3 | width: 50px;
4 | margin-left: 20px;
5 | margin-top: 10px;
6 | margin-bottom: 10px;
7 | margin-right: 20px;
8 | float: left;
9 | }
10 |
11 | #title {
12 | background-color: black;
13 | display: inline-block;
14 | width: 100%;
15 | }
16 |
17 | #searchBox {
18 | height: 20px;
19 | width: 800px;
20 | margin-left: 20px;
21 | margin-top: 20px;
22 | margin-bottom: 20px;
23 | margin-right: 20px;
24 | float: left;
25 | font-size: 1.5em;
26 | }
27 |
28 | #searchButton {
29 | height: 25px;
30 | margin-top: 20px;
31 | margin-bottom: 20px;
32 | margin-right: 20px;
33 | float: left;
34 | }
35 |
36 | .dropbtn {
37 | background-color: black;
38 | color: white;
39 | padding: 16px;
40 | font-size: 15px;
41 | border: none;
42 | cursor: pointer;
43 | }
44 |
45 | .dropdown {
46 | position: relative;
47 | float: left;
48 | }
49 |
50 | .dropdown-content {
51 | display: none;
52 | position: absolute;
53 | background-color: #f9f9f9;
54 | min-width: 160px;
55 | box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
56 | }
57 |
58 | .dropdown-content a {
59 | font-size: 14px;
60 | color: black;
61 | padding: 12px 16px;
62 | text-decoration: none;
63 | display: block;
64 | }
65 |
66 | .dropdown-content a:hover {background-color: #f1f1f1}
67 |
68 | .dropdown:hover .dropdown-content {
69 | display: block;
70 | }
71 |
72 | .dropdown:hover .dropbtn {
73 | background-color: gray;
74 | }
75 |
76 | #signInButton {
77 | color: yellow;
78 | margin-top: 20px;
79 | margin-bottom: 20px;
80 | margin-left: 20px;
81 | margin-right: 20px;
82 | float: left;
83 | }
84 | #kart {
85 | color: white;
86 | margin-top: 20px;
87 | margin-bottom: 20px;
88 | margin-left: 20px;
89 | margin-right: 20px;
90 | float: left;
91 | }
92 |
93 | #cartIcon {
94 | height: 30px;
95 | width: 30px;
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/templates/cart.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your Cart
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
Shopping Cart
42 |
43 | {% for row in products %}
44 |
45 |
46 |
47 |

48 |
49 |
50 |
{{row[1]}}
51 | In stock
52 |
Remove
53 |
54 |
55 | ${{row[2]}}
56 |
57 |
58 | {% endfor %}
59 |
60 |
61 | Subtotal : ${{totalPrice}}
62 |
63 |
64 |
65 | Proceed to checkout
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/templates/displayCategory.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Category: {{categoryName}}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
42 |
Showing all products of Category {{categoryName}}:
43 | {% for itemData in data %}
44 |
45 |
46 | {% for row in itemData %}
47 | |
48 | {{row[1]}}
49 | |
50 | {% endfor %}
51 |
52 |
53 | {% for row in itemData %}
54 |
55 |
56 |
57 |
58 | |
59 | {% endfor %}
60 |
61 |
62 | {% for row in itemData %}
63 | |
64 | ${{row[2]}}
65 | |
66 | {% endfor %}
67 |
68 |
69 | {% endfor %}
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/templates/productDescription.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Product Description
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
42 |
{{data[1]}}
43 |
44 |
45 |

46 |
47 |
48 |
49 |
Details
50 |
51 |
52 | | Name |
53 | {{data[1]}} |
54 |
55 |
56 | | Price |
57 | ${{data[2]}} |
58 |
59 |
60 | | Stock |
61 | {{data[5]}} |
62 |
63 |
64 |
Description
65 |
{{data[3]}}
66 |
67 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Welcome
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
42 |
Shop by Category:
43 |
44 | {% for row in categoryData %}
45 | - {{row[1]}}
46 | {% endfor %}
47 |
48 |
49 |
50 |
Items
51 | {% for data in itemData %}
52 |
53 |
54 | {% for row in data %}
55 | |
56 | {{row[1]}}
57 | |
58 | {% endfor %}
59 |
60 |
61 | {% for row in data %}
62 |
63 |
64 |
65 |
66 | |
67 | {% endfor %}
68 |
69 |
70 | {% for row in data %}
71 | |
72 | ${{row[2]}}
73 | |
74 | {% endfor %}
75 |
76 |
77 | {% endfor %}
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/templates/editProfile.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Edit Profile
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 | {% if not loggedIn %}
19 |
22 | {% else %}
23 |
24 |
25 |
31 |
32 | {% endif %}
33 |
39 |
40 |
41 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "6b7af0fb986b8f9bf5f7e6fb2745fcd4c3a3fa2b1745868783aa57098eb1dd17"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.8"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.org/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "click": {
20 | "hashes": [
21 | "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1",
22 | "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"
23 | ],
24 | "markers": "python_version >= '3.6'",
25 | "version": "==8.0.4"
26 | },
27 | "flask": {
28 | "hashes": [
29 | "sha256:59da8a3170004800a2837844bfa84d49b022550616070f7cb1a659682b2e7c9f",
30 | "sha256:e1120c228ca2f553b470df4a5fa927ab66258467526069981b3eb0a91902687d"
31 | ],
32 | "index": "pypi",
33 | "version": "==2.0.3"
34 | },
35 | "itsdangerous": {
36 | "hashes": [
37 | "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
38 | "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
39 | ],
40 | "markers": "python_version >= '3.7'",
41 | "version": "==2.1.2"
42 | },
43 | "jinja2": {
44 | "hashes": [
45 | "sha256:a2f09a92f358b96b5f6ca6ecb4502669c4acb55d8733bbb2b2c9c4af5564c605",
46 | "sha256:da424924c069a4013730d8dd010cbecac7e7bb752be388db3741688bffb48dc6"
47 | ],
48 | "markers": "python_version >= '3.7'",
49 | "version": "==3.1.0"
50 | },
51 | "markupsafe": {
52 | "hashes": [
53 | "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
54 | "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
55 | "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
56 | "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
57 | "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
58 | "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
59 | "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
60 | "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
61 | "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
62 | "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
63 | "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
64 | "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
65 | "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
66 | "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
67 | "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
68 | "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
69 | "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
70 | "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
71 | "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
72 | "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
73 | "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
74 | "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
75 | "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
76 | "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
77 | "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
78 | "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
79 | "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
80 | "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
81 | "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
82 | "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
83 | "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
84 | "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
85 | "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
86 | "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
87 | "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
88 | "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
89 | "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
90 | "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
91 | "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
92 | "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
93 | ],
94 | "markers": "python_version >= '3.7'",
95 | "version": "==2.1.1"
96 | },
97 | "pysqlite3": {
98 | "hashes": [
99 | "sha256:0352864898aa406beb762f4a620594c950a9a4430caab679bce574065698c8ac"
100 | ],
101 | "index": "pypi",
102 | "version": "==0.4.7"
103 | },
104 | "werkzeug": {
105 | "hashes": [
106 | "sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8",
107 | "sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"
108 | ],
109 | "markers": "python_version >= '3.6'",
110 | "version": "==2.0.3"
111 | }
112 | },
113 | "develop": {}
114 | }
115 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from flask import *
2 | import sqlite3, hashlib, os
3 | from werkzeug.utils import secure_filename
4 |
5 | app = Flask(__name__)
6 | app.secret_key = 'random string'
7 | UPLOAD_FOLDER = 'static/uploads'
8 | ALLOWED_EXTENSIONS = set(['jpeg', 'jpg', 'png', 'gif'])
9 | app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
10 |
11 | def getLoginDetails():
12 | with sqlite3.connect('database.db') as conn:
13 | cur = conn.cursor()
14 | if 'email' not in session:
15 | loggedIn = False
16 | firstName = ''
17 | noOfItems = 0
18 | else:
19 | loggedIn = True
20 | cur.execute("SELECT userId, firstName FROM users WHERE email = ?", (session['email'], ))
21 | userId, firstName = cur.fetchone()
22 | cur.execute("SELECT count(productId) FROM kart WHERE userId = ?", (userId, ))
23 | noOfItems = cur.fetchone()[0]
24 | conn.close()
25 | return (loggedIn, firstName, noOfItems)
26 |
27 | @app.route("/")
28 | def root():
29 | loggedIn, firstName, noOfItems = getLoginDetails()
30 | with sqlite3.connect('database.db') as conn:
31 | cur = conn.cursor()
32 | cur.execute('SELECT productId, name, price, description, image, stock FROM products')
33 | itemData = cur.fetchall()
34 | cur.execute('SELECT categoryId, name FROM categories')
35 | categoryData = cur.fetchall()
36 | itemData = parse(itemData)
37 | return render_template('home.html', itemData=itemData, loggedIn=loggedIn, firstName=firstName, noOfItems=noOfItems, categoryData=categoryData)
38 |
39 | @app.route("/add")
40 | def admin():
41 | with sqlite3.connect('database.db') as conn:
42 | cur = conn.cursor()
43 | cur.execute("SELECT categoryId, name FROM categories")
44 | categories = cur.fetchall()
45 | conn.close()
46 | return render_template('add.html', categories=categories)
47 |
48 | @app.route("/addItem", methods=["GET", "POST"])
49 | def addItem():
50 | if request.method == "POST":
51 | name = request.form['name']
52 | price = float(request.form['price'])
53 | description = request.form['description']
54 | stock = int(request.form['stock'])
55 | categoryId = int(request.form['category'])
56 |
57 | #Uploading image procedure
58 | image = request.files['image']
59 | if image and allowed_file(image.filename):
60 | filename = secure_filename(image.filename)
61 | image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
62 | imagename = filename
63 | with sqlite3.connect('database.db') as conn:
64 | try:
65 | cur = conn.cursor()
66 | cur.execute('''INSERT INTO products (name, price, description, image, stock, categoryId) VALUES (?, ?, ?, ?, ?, ?)''', (name, price, description, imagename, stock, categoryId))
67 | conn.commit()
68 | msg="added successfully"
69 | except:
70 | msg="error occured"
71 | conn.rollback()
72 | conn.close()
73 | print(msg)
74 | return redirect(url_for('root'))
75 |
76 | @app.route("/remove")
77 | def remove():
78 | with sqlite3.connect('database.db') as conn:
79 | cur = conn.cursor()
80 | cur.execute('SELECT productId, name, price, description, image, stock FROM products')
81 | data = cur.fetchall()
82 | conn.close()
83 | return render_template('remove.html', data=data)
84 |
85 | @app.route("/removeItem")
86 | def removeItem():
87 | productId = request.args.get('productId')
88 | with sqlite3.connect('database.db') as conn:
89 | try:
90 | cur = conn.cursor()
91 | cur.execute('DELETE FROM products WHERE productID = ?', (productId, ))
92 | conn.commit()
93 | msg = "Deleted successsfully"
94 | except:
95 | conn.rollback()
96 | msg = "Error occured"
97 | conn.close()
98 | print(msg)
99 | return redirect(url_for('root'))
100 |
101 | @app.route("/displayCategory")
102 | def displayCategory():
103 | loggedIn, firstName, noOfItems = getLoginDetails()
104 | categoryId = request.args.get("categoryId")
105 | with sqlite3.connect('database.db') as conn:
106 | cur = conn.cursor()
107 | cur.execute("SELECT products.productId, products.name, products.price, products.image, categories.name FROM products, categories WHERE products.categoryId = categories.categoryId AND categories.categoryId = ?", (categoryId, ))
108 | data = cur.fetchall()
109 | conn.close()
110 | categoryName = data[0][4]
111 | data = parse(data)
112 | return render_template('displayCategory.html', data=data, loggedIn=loggedIn, firstName=firstName, noOfItems=noOfItems, categoryName=categoryName)
113 |
114 | @app.route("/account/profile")
115 | def profileHome():
116 | if 'email' not in session:
117 | return redirect(url_for('root'))
118 | loggedIn, firstName, noOfItems = getLoginDetails()
119 | return render_template("profileHome.html", loggedIn=loggedIn, firstName=firstName, noOfItems=noOfItems)
120 |
121 | @app.route("/account/profile/edit")
122 | def editProfile():
123 | if 'email' not in session:
124 | return redirect(url_for('root'))
125 | loggedIn, firstName, noOfItems = getLoginDetails()
126 | with sqlite3.connect('database.db') as conn:
127 | cur = conn.cursor()
128 | cur.execute("SELECT userId, email, firstName, lastName, address1, address2, zipcode, city, state, country, phone FROM users WHERE email = ?", (session['email'], ))
129 | profileData = cur.fetchone()
130 | conn.close()
131 | return render_template("editProfile.html", profileData=profileData, loggedIn=loggedIn, firstName=firstName, noOfItems=noOfItems)
132 |
133 | @app.route("/account/profile/changePassword", methods=["GET", "POST"])
134 | def changePassword():
135 | if 'email' not in session:
136 | return redirect(url_for('loginForm'))
137 | if request.method == "POST":
138 | oldPassword = request.form['oldpassword']
139 | oldPassword = hashlib.md5(oldPassword.encode()).hexdigest()
140 | newPassword = request.form['newpassword']
141 | newPassword = hashlib.md5(newPassword.encode()).hexdigest()
142 | with sqlite3.connect('database.db') as conn:
143 | cur = conn.cursor()
144 | cur.execute("SELECT userId, password FROM users WHERE email = ?", (session['email'], ))
145 | userId, password = cur.fetchone()
146 | if (password == oldPassword):
147 | try:
148 | cur.execute("UPDATE users SET password = ? WHERE userId = ?", (newPassword, userId))
149 | conn.commit()
150 | msg="Changed successfully"
151 | except:
152 | conn.rollback()
153 | msg = "Failed"
154 | return render_template("changePassword.html", msg=msg)
155 | else:
156 | msg = "Wrong password"
157 | conn.close()
158 | return render_template("changePassword.html", msg=msg)
159 | else:
160 | return render_template("changePassword.html")
161 |
162 | @app.route("/updateProfile", methods=["GET", "POST"])
163 | def updateProfile():
164 | if request.method == 'POST':
165 | email = request.form['email']
166 | firstName = request.form['firstName']
167 | lastName = request.form['lastName']
168 | address1 = request.form['address1']
169 | address2 = request.form['address2']
170 | zipcode = request.form['zipcode']
171 | city = request.form['city']
172 | state = request.form['state']
173 | country = request.form['country']
174 | phone = request.form['phone']
175 | with sqlite3.connect('database.db') as con:
176 | try:
177 | cur = con.cursor()
178 | cur.execute('UPDATE users SET firstName = ?, lastName = ?, address1 = ?, address2 = ?, zipcode = ?, city = ?, state = ?, country = ?, phone = ? WHERE email = ?', (firstName, lastName, address1, address2, zipcode, city, state, country, phone, email))
179 |
180 | con.commit()
181 | msg = "Saved Successfully"
182 | except:
183 | con.rollback()
184 | msg = "Error occured"
185 | con.close()
186 | return redirect(url_for('editProfile'))
187 |
188 | @app.route("/loginForm")
189 | def loginForm():
190 | if 'email' in session:
191 | return redirect(url_for('root'))
192 | else:
193 | return render_template('login.html', error='')
194 |
195 | @app.route("/login", methods = ['POST', 'GET'])
196 | def login():
197 | if request.method == 'POST':
198 | email = request.form['email']
199 | password = request.form['password']
200 | if is_valid(email, password):
201 | session['email'] = email
202 | return redirect(url_for('root'))
203 | else:
204 | error = 'Invalid UserId / Password'
205 | return render_template('login.html', error=error)
206 |
207 | @app.route("/productDescription")
208 | def productDescription():
209 | loggedIn, firstName, noOfItems = getLoginDetails()
210 | productId = request.args.get('productId')
211 | with sqlite3.connect('database.db') as conn:
212 | cur = conn.cursor()
213 | cur.execute('SELECT productId, name, price, description, image, stock FROM products WHERE productId = ?', (productId, ))
214 | productData = cur.fetchone()
215 | conn.close()
216 | return render_template("productDescription.html", data=productData, loggedIn = loggedIn, firstName = firstName, noOfItems = noOfItems)
217 |
218 | @app.route("/addToCart")
219 | def addToCart():
220 | if 'email' not in session:
221 | return redirect(url_for('loginForm'))
222 | else:
223 | productId = int(request.args.get('productId'))
224 | with sqlite3.connect('database.db') as conn:
225 | cur = conn.cursor()
226 | cur.execute("SELECT userId FROM users WHERE email = ?", (session['email'], ))
227 | userId = cur.fetchone()[0]
228 | try:
229 | cur.execute("INSERT INTO kart (userId, productId) VALUES (?, ?)", (userId, productId))
230 | conn.commit()
231 | msg = "Added successfully"
232 | except:
233 | conn.rollback()
234 | msg = "Error occured"
235 | conn.close()
236 | return redirect(url_for('root'))
237 |
238 | @app.route("/cart")
239 | def cart():
240 | if 'email' not in session:
241 | return redirect(url_for('loginForm'))
242 | loggedIn, firstName, noOfItems = getLoginDetails()
243 | email = session['email']
244 | with sqlite3.connect('database.db') as conn:
245 | cur = conn.cursor()
246 | cur.execute("SELECT userId FROM users WHERE email = ?", (email, ))
247 | userId = cur.fetchone()[0]
248 | cur.execute("SELECT products.productId, products.name, products.price, products.image FROM products, kart WHERE products.productId = kart.productId AND kart.userId = ?", (userId, ))
249 | products = cur.fetchall()
250 | totalPrice = 0
251 | for row in products:
252 | totalPrice += row[2]
253 | return render_template("cart.html", products = products, totalPrice=totalPrice, loggedIn=loggedIn, firstName=firstName, noOfItems=noOfItems)
254 |
255 | @app.route("/removeFromCart")
256 | def removeFromCart():
257 | if 'email' not in session:
258 | return redirect(url_for('loginForm'))
259 | email = session['email']
260 | productId = int(request.args.get('productId'))
261 | with sqlite3.connect('database.db') as conn:
262 | cur = conn.cursor()
263 | cur.execute("SELECT userId FROM users WHERE email = ?", (email, ))
264 | userId = cur.fetchone()[0]
265 | try:
266 | cur.execute("DELETE FROM kart WHERE userId = ? AND productId = ?", (userId, productId))
267 | conn.commit()
268 | msg = "removed successfully"
269 | except:
270 | conn.rollback()
271 | msg = "error occured"
272 | conn.close()
273 | return redirect(url_for('root'))
274 |
275 | @app.route("/logout")
276 | def logout():
277 | session.pop('email', None)
278 | return redirect(url_for('root'))
279 |
280 | def is_valid(email, password):
281 | con = sqlite3.connect('database.db')
282 | cur = con.cursor()
283 | cur.execute('SELECT email, password FROM users')
284 | data = cur.fetchall()
285 | for row in data:
286 | if row[0] == email and row[1] == hashlib.md5(password.encode()).hexdigest():
287 | return True
288 | return False
289 |
290 | @app.route("/register", methods = ['GET', 'POST'])
291 | def register():
292 | if request.method == 'POST':
293 | #Parse form data
294 | password = request.form['password']
295 | email = request.form['email']
296 | firstName = request.form['firstName']
297 | lastName = request.form['lastName']
298 | address1 = request.form['address1']
299 | address2 = request.form['address2']
300 | zipcode = request.form['zipcode']
301 | city = request.form['city']
302 | state = request.form['state']
303 | country = request.form['country']
304 | phone = request.form['phone']
305 |
306 | with sqlite3.connect('database.db') as con:
307 | try:
308 | cur = con.cursor()
309 | cur.execute('INSERT INTO users (password, email, firstName, lastName, address1, address2, zipcode, city, state, country, phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (hashlib.md5(password.encode()).hexdigest(), email, firstName, lastName, address1, address2, zipcode, city, state, country, phone))
310 |
311 | con.commit()
312 |
313 | msg = "Registered Successfully"
314 | except:
315 | con.rollback()
316 | msg = "Error occured"
317 | con.close()
318 | return render_template("login.html", error=msg)
319 |
320 | @app.route("/registerationForm")
321 | def registrationForm():
322 | return render_template("register.html")
323 |
324 | def allowed_file(filename):
325 | return '.' in filename and \
326 | filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
327 |
328 | def parse(data):
329 | ans = []
330 | i = 0
331 | while i < len(data):
332 | curr = []
333 | for j in range(7):
334 | if i >= len(data):
335 | break
336 | curr.append(data[i])
337 | i += 1
338 | ans.append(curr)
339 | return ans
340 |
341 | if __name__ == '__main__':
342 | app.run(debug=True)
343 |
--------------------------------------------------------------------------------