mistpe commited on
Commit
f9e414d
·
verified ·
1 Parent(s): 478e8bf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -279
app.py CHANGED
@@ -1,14 +1,18 @@
1
- from flask import Flask, request, jsonify
2
- from flask_cors import CORS
3
- from pymongo import MongoClient
4
- from bson import ObjectId
5
  import os
6
  import oss2
 
 
7
  import bcrypt
8
- from datetime import datetime, timedelta
9
- import jwt
10
- from functools import wraps
11
- import random
 
 
 
 
 
 
12
  from dotenv import load_dotenv
13
 
14
  # 加载 .env 文件中的环境变量
@@ -17,300 +21,233 @@ load_dotenv()
17
  app = Flask(__name__)
18
  CORS(app)
19
 
20
- # MongoDB configuration
21
- # 从环境变量中获取 MongoDB 配置信息
22
- mongo_uri = os.getenv("MONGO_URI")
23
- client = MongoClient(mongo_uri)
24
- db = client['stylespace']
25
 
26
- if 'carts' not in db.list_collection_names():
27
- db.create_collection('carts')
28
-
29
  # 从环境变量中获取阿里云 OSS 配置信息
30
  access_key_id = os.getenv("OSS_ACCESS_KEY_ID")
31
  access_key_secret = os.getenv("OSS_ACCESS_KEY_SECRET")
32
  bucket_name = os.getenv("OSS_BUCKET_NAME")
33
  endpoint = os.getenv("OSS_ENDPOINT")
34
 
 
 
 
 
35
 
36
  # Create Aliyun OSS bucket object
37
  bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
38
 
39
- # JWT configuration
40
- app.config['SECRET_KEY'] = '1234' # Change this to a secure secret key
41
-
42
- def token_required(f):
43
- @wraps(f)
44
- def decorated(*args, **kwargs):
45
- token = request.headers.get('Authorization')
46
- if not token:
47
- return jsonify({'message': 'Token is missing!'}), 401
48
- try:
49
- token = token.split(" ")[1] if token.startswith("Bearer ") else token
50
- data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])
51
- current_user = db.users.find_one({'_id': ObjectId(data['user_id'])})
52
- if not current_user:
53
- raise jwt.InvalidTokenError
54
- except jwt.ExpiredSignatureError:
55
- return jsonify({'message': 'Token has expired!'}), 401
56
- except jwt.InvalidTokenError:
57
- return jsonify({'message': 'Invalid token!'}), 401
58
- return f(current_user, *args, **kwargs)
59
- return decorated
60
-
61
- @app.route('/api/auth/register', methods=['POST'])
62
- def register():
63
- data = request.json
64
- if db.users.find_one({'username': data['username']}):
65
- return jsonify({'message': 'Username already exists'}), 400
66
- if db.users.find_one({'email': data['email']}):
67
- return jsonify({'message': 'Email already exists'}), 400
68
- hashed_password = bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt())
69
- user = {
70
- 'username': data['username'],
71
- 'email': data['email'],
72
- 'password': hashed_password,
73
- 'created_at': datetime.utcnow()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
- result = db.users.insert_one(user)
76
- return jsonify({'message': 'User created successfully', 'id': str(result.inserted_id)}), 201
77
-
78
- @app.route('/api/auth/login', methods=['POST'])
79
- def login():
80
- data = request.json
81
- user = db.users.find_one({'username': data['username']})
82
- if user and bcrypt.checkpw(data['password'].encode('utf-8'), user['password']):
83
- token = jwt.encode(
84
- {'user_id': str(user['_id']), 'exp': datetime.utcnow() + timedelta(hours=24)},
85
- app.config['SECRET_KEY'],
86
- algorithm="HS256"
87
- )
88
- return jsonify({'token': token, 'user': {'id': str(user['_id']), 'username': user['username'], 'email': user['email']}}), 200
89
- return jsonify({'message': 'Invalid username or password'}), 401
90
-
91
- @app.route('/api/auth/verify-token', methods=['POST'])
92
- @token_required
93
- def verify_token(current_user):
94
- return jsonify({'user': {'id': str(current_user['_id']), 'username': current_user['username'], 'email': current_user['email']}}), 200
95
-
96
- @app.route('/api/auth/logout', methods=['POST'])
97
- @token_required
98
- def logout(current_user):
99
- # 由于使用JWT,服务器端不需要做特殊处理
100
- return jsonify({'message': 'Successfully logged out'}), 200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
- @app.route('/api/products', methods=['GET'])
103
- def get_products():
104
- product_type = request.args.get('type', 'all')
105
- limit = int(request.args.get('limit', 20))
106
 
107
- all_products = list(db.products.find())
 
108
 
109
- if product_type == 'hot':
110
- selected_products = random.sample(all_products, min(4, len(all_products)))
111
- elif product_type == 'new':
112
- selected_products = random.sample(all_products, min(4, len(all_products)))
113
- else:
114
- selected_products = all_products[:limit]
115
 
116
- result = []
117
- for product in selected_products:
118
- result.append({
119
- '_id': str(product['_id']),
120
- 'name': product.get('name', 'Unknown Product'),
121
- 'price': float(product.get('price', 0)),
122
- 'originalPrice': float(product.get('originalPrice', 0)),
123
- 'brief': product.get('brief', 'No description available'),
124
- 'image': product.get('images', [None])[0],
125
- 'description': product.get('description', ''),
126
- 'images': product.get('images', []),
127
- 'sizes': product.get('sizes', [])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  })
129
-
130
- return jsonify({'data': result}), 200
131
-
132
- @app.route('/api/products/<product_id>', methods=['GET'])
133
- def get_product_details(product_id):
134
- product = db.products.find_one({'_id': ObjectId(product_id)})
135
- if product:
136
- product['_id'] = str(product['_id'])
137
- return jsonify({'data': product}), 200
138
- return jsonify({'message': 'Product not found'}), 404
139
-
140
- @app.route('/api/cart', methods=['GET'])
141
- @token_required
142
- def get_cart(current_user):
143
- cart = db.carts.find_one({'user_id': str(current_user['_id'])})
144
- if cart:
145
- cart_items = []
146
- for item in cart['items']:
147
- product = db.products.find_one({'_id': item['product_id']})
148
- if product:
149
- cart_items.append({
150
- '_id': str(item['_id']),
151
- 'product_id': str(product['_id']),
152
- 'name': product['name'],
153
- 'price': product['price'],
154
- 'image': product['images'][0] if product['images'] else None,
155
- 'quantity': item['quantity'],
156
- 'size': item['size']
157
- })
158
- return jsonify({'data': cart_items}), 200
159
  else:
160
- return jsonify({'data': []}), 200
161
-
162
- @app.route('/api/cart', methods=['POST'])
163
- @token_required
164
- def add_to_cart(current_user):
165
- data = request.json
166
- cart = db.carts.find_one({'user_id': str(current_user['_id'])})
167
- if not cart:
168
- cart = {
169
- 'user_id': str(current_user['_id']),
170
- 'items': []
171
- }
172
- result = db.carts.insert_one(cart)
173
- cart['_id'] = result.inserted_id
174
 
175
- item = next((item for item in cart['items'] if str(item['product_id']) == data['productId'] and item['size'] == data['size']), None)
176
- if item:
177
- item['quantity'] += data['quantity']
 
 
 
 
 
 
 
 
 
178
  else:
179
- cart['items'].append({
180
- '_id': ObjectId(),
181
- 'product_id': ObjectId(data['productId']),
182
- 'quantity': data['quantity'],
183
- 'size': data['size']
184
- })
185
-
186
- db.carts.update_one({'_id': cart['_id']}, {'$set': cart})
187
-
188
- return jsonify({'message': 'Item added to cart successfully'}), 200
189
-
190
- @app.route('/api/cart/<item_id>', methods=['PUT'])
191
- @token_required
192
- def update_cart_item(current_user, item_id):
193
- data = request.json
194
- cart = db.carts.find_one({'user_id': str(current_user['_id'])})
195
- if cart:
196
- for item in cart['items']:
197
- if str(item['_id']) == item_id:
198
- item['quantity'] = data['quantity']
199
- break
200
- db.carts.update_one({'_id': cart['_id']}, {'$set': cart})
201
-
202
- updated_item = next((item for item in cart['items'] if str(item['_id']) == item_id), None)
203
- if updated_item:
204
- product = db.products.find_one({'_id': updated_item['product_id']})
205
- if product:
206
- return jsonify({
207
- 'data': {
208
- '_id': str(updated_item['_id']),
209
- 'product_id': str(product['_id']),
210
- 'name': product['name'],
211
- 'price': product['price'],
212
- 'image': product['images'][0] if product['images'] else None,
213
- 'quantity': updated_item['quantity'],
214
- 'size': updated_item['size']
215
- }
216
- }), 200
217
-
218
- return jsonify({'message': 'Cart item updated successfully'}), 200
219
- return jsonify({'message': 'Cart not found'}), 404
220
-
221
- @app.route('/api/cart/<item_id>', methods=['DELETE'])
222
- @token_required
223
- def remove_from_cart(current_user, item_id):
224
- cart = db.carts.find_one({'user_id': str(current_user['_id'])})
225
- if cart:
226
- cart['items'] = [item for item in cart['items'] if str(item['_id']) != item_id]
227
- db.carts.update_one({'_id': cart['_id']}, {'$set': cart})
228
- return jsonify({'message': 'Item removed from cart successfully'}), 200
229
- return jsonify({'message': 'Cart not found'}), 404
230
 
231
- @app.route('/api/orders', methods=['POST'])
232
- @token_required
233
- def create_order(current_user):
234
- data = request.json
235
- order = {
236
- 'user_id': str(current_user['_id']),
237
- 'orderNumber': generate_order_number(),
238
- 'items': data['items'],
239
- 'subtotal': sum(item['price'] * item['quantity'] for item in data['items']),
240
- 'shippingFee': 10, # 固定运费,您可以根据需要修改
241
- 'total': sum(item['price'] * item['quantity'] for item in data['items']) + 10,
242
- 'status': 'unpaid',
243
- 'createdAt': datetime.utcnow(),
244
- 'updatedAt': datetime.utcnow(),
245
- 'paymentMethod': 'Pending',
246
- 'shippingAddress': data.get('shippingAddress', {})
247
- }
248
- result = db.orders.insert_one(order)
249
- return jsonify({'message': 'Order created successfully', 'order_id': str(result.inserted_id)}), 201
250
-
251
- @app.route('/api/orders/<order_id>', methods=['GET'])
252
- @token_required
253
- def get_order_details(current_user, order_id):
254
- order = db.orders.find_one({'_id': ObjectId(order_id), 'user_id': str(current_user['_id'])})
255
- if order:
256
- order['_id'] = str(order['_id'])
257
- return jsonify({'data': order}), 200
258
- return jsonify({'message': 'Order not found'}), 404
259
-
260
- @app.route('/api/orders/<order_id>/status', methods=['PUT'])
261
- @token_required
262
- def update_order_status(current_user, order_id):
263
- data = request.json
264
- new_status = data.get('status')
265
- if not new_status:
266
- return jsonify({'message': 'Status is required'}), 400
267
-
268
- order = db.orders.find_one({'_id': ObjectId(order_id), 'user_id': str(current_user['_id'])})
269
- if not order:
270
- return jsonify({'message': 'Order not found'}), 404
271
-
272
- update_data = {
273
- 'status': new_status,
274
- 'updatedAt': datetime.utcnow()
275
- }
276
-
277
- if new_status == 'unshipped':
278
- update_data['paymentMethod'] = data.get('paymentMethod', 'Not specified')
279
-
280
- db.orders.update_one({'_id': ObjectId(order_id)}, {'$set': update_data})
281
-
282
- return jsonify({'message': 'Order status updated successfully'}), 200
283
-
284
- @app.route('/api/orders', methods=['GET'])
285
- @token_required
286
- def get_user_orders(current_user):
287
- status = request.args.get('status')
288
- query = {'user_id': str(current_user['_id'])}
289
- if status:
290
- query['status'] = status
291
 
292
- orders = list(db.orders.find(query).sort('createdAt', -1))
293
- for order in orders:
294
- order['_id'] = str(order['_id'])
295
 
296
- return jsonify({'data': orders}), 200
297
-
298
- @app.route('/api/upload', methods=['POST'])
299
- @token_required
300
- def upload_image(current_user):
301
- if 'file' not in request.files:
302
- return jsonify({'message': 'No file part in the request'}), 400
303
- file = request.files['file']
304
- if file.filename == '':
305
- return jsonify({'message': 'No file selected for uploading'}), 400
306
- if file:
307
- filename = f"uploads/{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}"
308
- bucket.put_object(filename, file)
309
- url = f"https://{bucket_name}.{endpoint}/{filename}"
310
- return jsonify({'message': 'File uploaded successfully', 'url': url}), 200
311
-
312
- def generate_order_number():
313
- return f"ORD{datetime.utcnow().strftime('%Y%m%d%H%M%S')}{random.randint(1000, 9999)}"
314
 
315
  if __name__ == '__main__':
316
  app.run(host='0.0.0.0', port=7860, debug=True)
 
 
 
 
 
1
  import os
2
  import oss2
3
+ from pymongo import MongoClient
4
+ from pymongo.server_api import ServerApi
5
  import bcrypt
6
+ from datetime import datetime
7
+ from flask import Flask, request, jsonify
8
+ from flask_cors import CORS
9
+ import json
10
+ import websocket
11
+ import uuid
12
+ import urllib.request
13
+ import urllib.parse
14
+ import requests
15
+ from bson.objectid import ObjectId
16
  from dotenv import load_dotenv
17
 
18
  # 加载 .env 文件中的环境变量
 
21
  app = Flask(__name__)
22
  CORS(app)
23
 
24
+ # ComfyUI 设置
25
+ SERVER_ADDRESS = "127.0.0.1:8188"
26
+ CLIENT_ID = str(uuid.uuid4())
 
 
27
 
 
 
 
28
  # 从环境变量中获取阿里云 OSS 配置信息
29
  access_key_id = os.getenv("OSS_ACCESS_KEY_ID")
30
  access_key_secret = os.getenv("OSS_ACCESS_KEY_SECRET")
31
  bucket_name = os.getenv("OSS_BUCKET_NAME")
32
  endpoint = os.getenv("OSS_ENDPOINT")
33
 
34
+ # MongoDB configuration
35
+ # 从环境变量中获取 MongoDB 配置信息
36
+ uri = os.getenv("MONGO_URI")
37
+ client = MongoClient(uri, server_api=ServerApi('1'))
38
 
39
  # Create Aliyun OSS bucket object
40
  bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
41
 
42
+ try:
43
+ client.admin.command('ping')
44
+ print("Successfully connected to MongoDB!")
45
+ except Exception as e:
46
+ print(f"Failed to connect to MongoDB: {e}")
47
+ exit(1)
48
+
49
+ db = client['ai_image_generator']
50
+ images_collection = db['images']
51
+
52
+ # ComfyUI workflow (省略具体内容)
53
+ WORKFLOW = {
54
+ "3": {
55
+ "inputs": {
56
+ "seed": 1048756903667323,
57
+ "steps": 20,
58
+ "cfg": 8,
59
+ "sampler_name": "euler",
60
+ "scheduler": "normal",
61
+ "denoise": 1,
62
+ "model": ["4", 0],
63
+ "positive": ["6", 0],
64
+ "negative": ["7", 0],
65
+ "latent_image": ["5", 0]
66
+ },
67
+ "class_type": "KSampler"
68
+ },
69
+ "4": {
70
+ "inputs": {
71
+ "ckpt_name": "sd_xl_base_1.0.safetensors"
72
+ },
73
+ "class_type": "CheckpointLoaderSimple"
74
+ },
75
+ "5": {
76
+ "inputs": {
77
+ "width": 512,
78
+ "height": 512,
79
+ "batch_size": 1
80
+ },
81
+ "class_type": "EmptyLatentImage"
82
+ },
83
+ "6": {
84
+ "inputs": {
85
+ "text": "",
86
+ "clip": ["4", 1]
87
+ },
88
+ "class_type": "CLIPTextEncode"
89
+ },
90
+ "7": {
91
+ "inputs": {
92
+ "text": "text, watermark",
93
+ "clip": ["4", 1]
94
+ },
95
+ "class_type": "CLIPTextEncode"
96
+ },
97
+ "8": {
98
+ "inputs": {
99
+ "samples": ["3", 0],
100
+ "vae": ["4", 2]
101
+ },
102
+ "class_type": "VAEDecode"
103
+ },
104
+ "9": {
105
+ "inputs": {
106
+ "filename_prefix": "ComfyUI",
107
+ "images": ["8", 0]
108
+ },
109
+ "class_type": "SaveImage"
110
  }
111
+ }
112
+
113
+ def queue_prompt(prompt):
114
+ p = {"prompt": prompt, "client_id": CLIENT_ID}
115
+ data = json.dumps(p).encode('utf-8')
116
+ req = urllib.request.Request(f"http://{SERVER_ADDRESS}/prompt", data=data)
117
+ return json.loads(urllib.request.urlopen(req).read())
118
+
119
+ def get_image(filename, subfolder, folder_type):
120
+ data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
121
+ url_values = urllib.parse.urlencode(data)
122
+ with urllib.request.urlopen(f"http://{SERVER_ADDRESS}/view?{url_values}") as response:
123
+ return response.read()
124
+
125
+ def get_history(prompt_id):
126
+ with urllib.request.urlopen(f"http://{SERVER_ADDRESS}/history/{prompt_id}") as response:
127
+ return json.loads(response.read())
128
+
129
+ def get_images(ws, prompt):
130
+ prompt_id = queue_prompt(prompt)['prompt_id']
131
+ print(f'Prompt ID: {prompt_id}')
132
+
133
+ while True:
134
+ out = ws.recv()
135
+ if isinstance(out, str):
136
+ message = json.loads(out)
137
+ if message['type'] == 'executing':
138
+ data = message['data']
139
+ if data['node'] is None and data['prompt_id'] == prompt_id:
140
+ print('Execution completed')
141
+ break
142
+ else:
143
+ continue # Ignore binary data (previews)
144
+
145
+ history = get_history(prompt_id)[prompt_id]
146
+ output_images = {}
147
+
148
+ for node_id, node_output in history['outputs'].items():
149
+ if 'images' in node_output:
150
+ images_output = []
151
+ for image in node_output['images']:
152
+ image_data = get_image(image['filename'], image['subfolder'], image['type'])
153
+ images_output.append(image_data)
154
+ output_images[node_id] = images_output
155
+
156
+ return output_images
157
+
158
+ def translate_to_english(text):
159
+ url = os.getenv("DEEP_URI")
160
+ payload = json.dumps({
161
+ "text": text,
162
+ "source_lang": "auto",
163
+ "target_lang": "EN"
164
+ })
165
+ headers = {
166
+ 'Content-Type': 'application/json'
167
+ }
168
+ try:
169
+ response = requests.post(url, headers=headers, data=payload)
170
+ response.raise_for_status()
171
+ result = response.json()
172
+ return result.get('data', text)
173
+ except requests.RequestException as e:
174
+ print(f"翻译请求失败: {e}")
175
+ return text
176
+
177
+ @app.route('/generate', methods=['POST'])
178
+ def generate_image():
179
+ prompt = request.json['prompt']
180
+
181
+ english_prompt = translate_to_english(prompt)
182
+ print(f"Original prompt: {prompt}")
183
+ print(f"Translated prompt: {english_prompt}")
184
 
185
+ ws = websocket.create_connection(f"ws://{SERVER_ADDRESS}/ws?clientId={CLIENT_ID}")
 
 
 
186
 
187
+ workflow = WORKFLOW.copy()
188
+ workflow["6"]["inputs"]["text"] = english_prompt
189
 
190
+ images = get_images(ws, workflow)
191
+ ws.close()
 
 
 
 
192
 
193
+ if images:
194
+ image_data = list(images.values())[0][0]
195
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
196
+ filename = f"generated_image_{timestamp}.png"
197
+ oss_path = f"images/{filename}"
198
+
199
+ # Upload to Aliyun OSS
200
+ bucket.put_object(oss_path, image_data)
201
+
202
+ # Get the public URL
203
+ image_url = f"https://{bucket_name}.{endpoint}/{oss_path}"
204
+
205
+ # Save to MongoDB
206
+ image_doc = {
207
+ "prompt": prompt,
208
+ "english_prompt": english_prompt,
209
+ "url": image_url,
210
+ "filename": filename,
211
+ "created_at": datetime.utcnow(),
212
+ "is_public": False
213
+ }
214
+ result = images_collection.insert_one(image_doc)
215
+
216
+ return jsonify({
217
+ "status": "success",
218
+ "filename": filename,
219
+ "url": image_url,
220
+ "id": str(result.inserted_id)
221
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  else:
223
+ return jsonify({"status": "error", "message": "Failed to generate image"})
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
+ @app.route('/add-to-public-gallery', methods=['POST'])
226
+ def add_to_public_gallery():
227
+ image_id = request.json['image_id']
228
+
229
+ # Update the image document in MongoDB
230
+ result = images_collection.update_one(
231
+ {"_id": ObjectId(image_id)},
232
+ {"$set": {"is_public": True}}
233
+ )
234
+
235
+ if result.modified_count > 0:
236
+ return jsonify({"status": "success", "message": "Image added to public gallery"})
237
  else:
238
+ return jsonify({"status": "error", "message": "Failed to add image to public gallery"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
+ @app.route('/api/gallery', methods=['GET'])
241
+ def get_gallery_images():
242
+ # Temporarily return all images, regardless of is_public status
243
+ all_images = list(images_collection.find().sort("created_at", -1).limit(20))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
+ # Convert ObjectId to string for JSON serialization
246
+ for image in all_images:
247
+ image['_id'] = str(image['_id'])
248
 
249
+ print(f"Returning {len(all_images)} images") # Add this line for debugging
250
+ return jsonify(all_images)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  if __name__ == '__main__':
253
  app.run(host='0.0.0.0', port=7860, debug=True)