-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmypython.py
More file actions
226 lines (187 loc) · 7.44 KB
/
Copy pathmypython.py
File metadata and controls
226 lines (187 loc) · 7.44 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import subprocess
import sys
def install_sqlite3():
"""
Check if sqlite3 is available and install if needed.
Note: sqlite3 is part of Python's standard library since Python 2.5
"""
try:
import sqlite3
print("sqlite3 is already available (part of Python standard library)")
except ImportError:
print("sqlite3 not found. Installing...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "pysqlite3"])
print("sqlite3 installed successfully")
except subprocess.CalledProcessError:
print("Failed to install sqlite3. Please install manually.")
sys.exit(1)
# Ensure cars.db file has read and write permissions
import os
db_path = 'cars.db'
if os.path.exists(db_path):
os.chmod(db_path, 0o666) # Set read and write permissions for owner, group, and others
# Ensure sqlite3 is available before running the application
install_sqlite3()
import sqlite3
from werkzeug.utils import secure_filename
class Car:
def __init__(self, make: str, model: str, year: int, color: str,is_running:bool, fuel_type: str, price: int, transmission: str, mileage: int):
self.make = make
self.model = model
self.year = year
self.color = color
self.is_running = is_running
self.fuel_type = fuel_type
self.price = price
self.transmission = transmission
self.mileage = mileage
def start(self):
self.is_running = True
print(f"{self.year} {self.make} {self.model} is now running.")
def stop(self):
self.is_running = False
print(f"{self.year} {self.make} {self.model} has stopped.")
def __str__(self):
return f"{self.year} {self.color} {self.make} {self.model}"
class CarManager:
def __init__(self):
self.cars = []
# Initialize SQLite database connection
self.conn = sqlite3.connect('cars.db')
self.cursor = self.conn.cursor()
# Create cars table if it doesn't exist
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS cars (
id INTEGER PRIMARY KEY AUTOINCREMENT,
make TEXT NOT NULL,
model TEXT NOT NULL,
year INTEGER NOT NULL,
color TEXT NOT NULL,
is_running BOOLEAN DEFAULT FALSE,
image_file TEXT,
fuel_type TEXT,
price INTEGER,
transmission TEXT,
mileage INTEGER
)
''')
self.conn.commit()
def create_car(self, car):
# 1. Create a local connection for this specific thread/request
conn = sqlite3.connect('cars.db')
cursor = conn.cursor()
try:
# 2. Add to your local list (if you are still using self.cars)
self.cars.append(car)
# 3. Use the local 'cursor' (NOT self.cursor) to insert
cursor.execute('''
INSERT INTO cars (make, model, year, color, is_running, image_file, fuel_type, price, transmission, mileage)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?)
''', (car.make, car.model, car.year, car.color, car.is_running, None, car.fuel_type if hasattr(car, 'fuel_type') else None, car.price if hasattr(car, 'price') else None, car.transmission if hasattr(car, 'transmission') else None, getattr(car, 'mileage', None)))
# 4. Use the local 'conn' (NOT self.conn) to commit
conn.commit()
print(f"Added: {car}")
except Exception as e:
print(f"Database error: {e}")
raise e # Re-raise so the API knows it failed
finally:
# 5. Always close the connection for this thread
conn.close()
def add_car(self, car, image_file=None):
# 1. Handle image saving
image_filename = None
if image_file and image_file.filename != '':
# Use secure_filename to prevent directory traversal attacks
image_filename = secure_filename(image_file.filename)
# Ensure path is relative to the app execution directory
upload_folder = os.path.join('static', 'uploads')
os.makedirs(upload_folder, exist_ok=True)
upload_path = os.path.join(upload_folder, image_filename)
image_file.save(upload_path)
# 2. Database Operation
# Using a context manager (with) for the connection is even safer
try:
with sqlite3.connect('cars.db') as conn:
cursor = conn.cursor()
# Ensure the car object has all these attributes!
# Note: Added car.is_running - make sure your Car class has this.
cursor.execute('''
INSERT INTO cars (make, model, year, color, is_running, image_file, fuel_type, price, transmission, mileage)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
car.make,
car.model,
car.year,
car.color,
getattr(car, 'is_running', True), # Fallback to True if missing
image_filename,
car.fuel_type if hasattr(car, 'fuel_type') else None,
car.price if hasattr(car, 'price') else None,
car.transmission if hasattr(car, 'transmission') else None,
car.mileage if hasattr(car, 'mileage') else None
))
conn.commit()
# Update local list only if DB insert succeeds
self.cars.append(car)
print(f"Successfully added {car.make} to DB and local list.")
except sqlite3.Error as e:
print(f"SQLite error: {e}")
raise e
except Exception as e:
print(f"General error in add_car: {e}")
raise e
# def add_car(self, car):
# self.cars.append(car)
# # Insert car into SQLite database
# self.cursor.execute('''
# INSERT INTO cars (make, model, year, color, is_running)
# VALUES (?, ?, ?, ?, ?)
# ''', (car.make, car.model, car.year, car.color, car.is_running))
# self.conn.commit()
# print(f"Added: {car}")
def remove_car(self, car):
self.cars.remove(car)
# Remove car from SQLite database
self.cursor.execute('''
DELETE FROM cars WHERE make = ? AND model = ? AND year = ? AND color = ?
''', (car.make, car.model, car.year, car.color))
self.conn.commit()
print(f"Removed: {car}")
import sqlite3
def list_cars(self):
# 1. Connect inside the method to avoid Thread errors
conn = sqlite3.connect('cars.db')
# 2. Use Row factory to allow column name access (e.g., car['make'])
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
try:
cursor.execute("SELECT * FROM cars")
rows = cursor.fetchall()
# 3. Convert sqlite3.Row objects into a list of real dictionaries
cars_list = [dict(row) for row in rows]
return cars_list
finally:
conn.close()
def find_car(self, make, model):
for car in self.cars:
if car.make == make and car.model == model:
return car
return None
def get_car(self, car_id):
with sqlite3.connect('cars.db') as conn:
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM cars WHERE id = ?", (car_id,))
row = cursor.fetchone()
return dict(row) if row else None
def delete_car_by_id(self, car_id):
with sqlite3.connect('cars.db') as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM cars WHERE id = ?", (car_id,))
conn.commit()
return True
def __del__(self):
# Close database connection when CarManager is destroyed
if hasattr(self, 'conn'):
self.conn.close()