huylaughmad commited on
Commit
0f16180
·
verified ·
1 Parent(s): c38465b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +390 -181
app.py CHANGED
@@ -4,7 +4,8 @@ import json
4
  from flask import Flask, render_template, request, redirect, url_for, abort, flash, jsonify
5
  from flask_httpauth import HTTPBasicAuth
6
  from werkzeug.security import generate_password_hash, check_password_hash
7
- from huggingface_hub import hf_hub_download, upload_file, HfApi
 
8
  import logging
9
  import tempfile
10
  import fcntl
@@ -12,12 +13,16 @@ from datetime import datetime
12
 
13
  app = Flask(__name__)
14
  app.config['SECRET_KEY'] = os.getenv("FLASK_SECRET_KEY", "your-secret-key-here")
 
15
  auth = HTTPBasicAuth()
16
 
17
  # Thiết lập logging
18
  logging.basicConfig(level=logging.INFO)
19
  logger = logging.getLogger(__name__)
20
 
 
 
 
21
  # Cấu hình người dùng
22
  ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin")
23
  ADMIN_PASSWORD_HASH = generate_password_hash(os.getenv("ADMIN_PASSWORD", "password"))
@@ -115,7 +120,7 @@ def init_db():
115
  CREATE TABLE IF NOT EXISTS case_studies (
116
  id INTEGER PRIMARY KEY AUTOINCREMENT,
117
  title TEXT NOT NULL,
118
- treatment TEXT,
119
  description TEXT,
120
  before_image TEXT,
121
  after_image TEXT,
@@ -124,10 +129,10 @@ def init_db():
124
  patient_rating TEXT DEFAULT '5',
125
  patient_avatar TEXT,
126
  status TEXT DEFAULT 'draft',
127
- date TEXT,
128
  duration TEXT,
129
  visits TEXT,
130
- case_id TEXT,
131
  seo_title TEXT,
132
  seo_description TEXT,
133
  seo_keywords TEXT,
@@ -150,7 +155,7 @@ def init_db():
150
  CREATE TABLE IF NOT EXISTS pages (
151
  id INTEGER PRIMARY KEY AUTOINCREMENT,
152
  title TEXT NOT NULL,
153
- slug TEXT NOT NULL,
154
  content TEXT,
155
  status TEXT DEFAULT 'draft',
156
  template TEXT DEFAULT 'default',
@@ -177,7 +182,7 @@ def init_db():
177
  CREATE TABLE IF NOT EXISTS posts (
178
  id INTEGER PRIMARY KEY AUTOINCREMENT,
179
  title TEXT NOT NULL,
180
- slug TEXT NOT NULL,
181
  content TEXT,
182
  status TEXT DEFAULT 'draft',
183
  categories TEXT,
@@ -199,7 +204,7 @@ def init_db():
199
  ('10 Dental Care Tips', 'dental-care-tips', '<p>Learn how to maintain a healthy smile with these tips...</p>', 'published', 'Dental Care', 'teeth,care', 'Top 10 dental care tips for a healthy smile.', 'Dental Care Tips', 'Learn dental care tips.', 'dental,care,tips', 'https://images.unsplash.com/photo-1588776814546-1ffcf47267a5', '2025-04-28')
200
  ''')
201
 
202
- # Các bảng khác (giữ nguyên từ mã hiện tại)
203
  cursor.execute('''
204
  CREATE TABLE IF NOT EXISTS our_story (
205
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -294,6 +299,17 @@ def init_db():
294
  FOREIGN KEY (case_id) REFERENCES case_studies(id)
295
  )
296
  ''')
 
 
 
 
 
 
 
 
 
 
 
297
  cursor.execute('CREATE INDEX IF NOT EXISTS idx_pjm_case_id ON patient_journey_milestones(case_id)')
298
 
299
  conn.commit()
@@ -329,38 +345,77 @@ def add_case():
329
  posts = [dict(row) for row in cursor.fetchall()]
330
 
331
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  cursor.execute('''
333
  INSERT INTO case_studies (
334
  title, treatment, description, before_image, after_image,
335
  patient_name, patient_age, patient_rating, patient_avatar,
336
  status, date, duration, visits, case_id,
337
- seo_title, seo_description, seo_keywords, category, tag
338
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
339
  ''', (
340
- request.form['case-title'],
341
- request.form['case-treatment'],
342
- request.form['case-description'],
343
- request.form.get('case-before-image', ''),
344
- request.form.get('case-after-image', ''),
345
- request.form.get('case-patient-name', ''),
346
- request.form.get('case-patient-age', ''),
347
- request.form.get('case-patient-rating', '5'),
348
- request.form.get('case-patient-avatar', ''),
349
- request.form.get('case-status', 'draft'),
350
- request.form.get('case-date', ''),
351
- request.form.get('case-duration', ''),
352
- request.form.get('case-visits', ''),
353
- request.form.get('case-id', ''),
354
- request.form.get('case-seo-title', ''),
355
- request.form.get('case-seo-description', ''),
356
- request.form.get('case-seo-keywords', ''),
357
- request.form.get('case-category', ''),
358
- request.form.get('case-tag', '')
359
  ))
360
  conn.commit()
361
  update_db_to_huggingface()
362
  conn.close()
363
- return redirect(url_for('cms'))
 
364
 
365
  conn.close()
366
  return render_template('cms.html', section='case-editor-section', case=None, cases=cases, pages=pages, posts=posts)
@@ -387,39 +442,78 @@ def edit_case(id):
387
  case = dict(case)
388
 
389
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  cursor.execute('''
391
  UPDATE case_studies
392
  SET title = ?, treatment = ?, description = ?, before_image = ?, after_image = ?,
393
  patient_name = ?, patient_age = ?, patient_rating = ?, patient_avatar = ?,
394
  status = ?, date = ?, duration = ?, visits = ?, case_id = ?,
395
- seo_title = ?, seo_description = ?, seo_keywords = ?, category = ?, tag = ?
396
  WHERE id = ?
397
  ''', (
398
- request.form['case-title'],
399
- request.form['case-treatment'],
400
- request.form['case-description'],
401
- request.form.get('case-before-image', ''),
402
- request.form.get('case-after-image', ''),
403
- request.form.get('case-patient-name', ''),
404
- request.form.get('case-patient-age', ''),
405
- request.form.get('case-patient-rating', '5'),
406
- request.form.get('case-patient-avatar', ''),
407
- request.form.get('case-status', 'draft'),
408
- request.form.get('case-date', ''),
409
- request.form.get('case-duration', ''),
410
- request.form.get('case-visits', ''),
411
- request.form.get('case-id', ''),
412
- request.form.get('case-seo-title', ''),
413
- request.form.get('case-seo-description', ''),
414
- request.form.get('case-seo-keywords', ''),
415
- request.form.get('case-category', ''),
416
- request.form.get('case-tag', ''),
417
  id
418
  ))
419
  conn.commit()
420
  update_db_to_huggingface()
421
  conn.close()
422
- return redirect(url_for('cms'))
 
423
 
424
  conn.close()
425
  return render_template('cms.html', section='case-editor-section', case=case, cases=cases, pages=pages, posts=posts)
@@ -434,7 +528,8 @@ def delete_case(id):
434
  conn.commit()
435
  update_db_to_huggingface()
436
  conn.close()
437
- return redirect(url_for('cms'))
 
438
 
439
  # Route để thêm page mới
440
  @app.route('/cms/pages/new', methods=['GET', 'POST'])
@@ -451,28 +546,49 @@ def add_page():
451
  posts = [dict(row) for row in cursor.fetchall()]
452
 
453
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  cursor.execute('''
455
  INSERT INTO pages (
456
  title, slug, content, status, template, parent_id,
457
  seo_title, seo_description, seo_keywords, featured_image, last_modified
458
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
459
  ''', (
460
- request.form['page-title'],
461
- request.form['page-slug'],
462
- request.form['page-content'],
463
- request.form.get('page-status', 'draft'),
464
- request.form.get('page-template', 'default'),
465
- request.form.get('page-parent', 0, type=int),
466
- request.form.get('seo-title', ''),
467
- request.form.get('seo-description', ''),
468
- request.form.get('seo-keywords', ''),
469
- request.form.get('featured-image', ''),
470
  datetime.now().strftime('%Y-%m-%d %H:%M:%S')
471
  ))
472
  conn.commit()
473
  update_db_to_huggingface()
474
  conn.close()
475
- return redirect(url_for('cms'))
 
476
 
477
  conn.close()
478
  return render_template('cms.html', section='page-editor-section', page=None, cases=cases, pages=pages, posts=posts)
@@ -499,6 +615,34 @@ def edit_page(id):
499
  page = dict(page)
500
 
501
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  cursor.execute('''
503
  UPDATE pages
504
  SET title = ?, slug = ?, content = ?, status = ?, template = ?, parent_id = ?,
@@ -506,23 +650,16 @@ def edit_page(id):
506
  last_modified = ?
507
  WHERE id = ?
508
  ''', (
509
- request.form['page-title'],
510
- request.form['page-slug'],
511
- request.form['page-content'],
512
- request.form.get('page-status', 'draft'),
513
- request.form.get('page-template', 'default'),
514
- request.form.get('page-parent', 0, type=int),
515
- request.form.get('seo-title', ''),
516
- request.form.get('seo-description', ''),
517
- request.form.get('seo-keywords', ''),
518
- request.form.get('featured-image', ''),
519
  datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
520
  id
521
  ))
522
  conn.commit()
523
  update_db_to_huggingface()
524
  conn.close()
525
- return redirect(url_for('cms'))
 
526
 
527
  conn.close()
528
  return render_template('cms.html', section='page-editor-section', page=page, cases=cases, pages=pages, posts=posts)
@@ -537,7 +674,8 @@ def delete_page(id):
537
  conn.commit()
538
  update_db_to_huggingface()
539
  conn.close()
540
- return redirect(url_for('cms'))
 
541
 
542
  # Route để thêm post mới
543
  @app.route('/cms/posts/new', methods=['GET', 'POST'])
@@ -554,29 +692,50 @@ def add_post():
554
  posts = [dict(row) for row in cursor.fetchall()]
555
 
556
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  cursor.execute('''
558
  INSERT INTO posts (
559
  title, slug, content, status, categories, tags, excerpt,
560
  seo_title, seo_description, seo_keywords, featured_image, publish_date
561
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
562
  ''', (
563
- request.form['post-title'],
564
- request.form['post-slug'],
565
- request.form['post-content'],
566
- request.form.get('post-status', 'draft'),
567
- ','.join(request.form.getlist('post-categories')),
568
- request.form.get('post-tags', ''),
569
- request.form.get('post-excerpt', ''),
570
- request.form.get('post-seo-title', ''),
571
- request.form.get('post-seo-description', ''),
572
- request.form.get('post-seo-keywords', ''),
573
- request.form.get('post-featured-image', ''),
574
- request.form.get('post-publish-date', '')
575
  ))
576
  conn.commit()
577
  update_db_to_huggingface()
578
  conn.close()
579
- return redirect(url_for('cms'))
 
580
 
581
  conn.close()
582
  return render_template('cms.html', section='post-editor-section', post=None, cases=cases, pages=pages, posts=posts)
@@ -603,6 +762,36 @@ def edit_post(id):
603
  post = dict(post)
604
 
605
  if request.method == 'POST':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
  cursor.execute('''
607
  UPDATE posts
608
  SET title = ?, slug = ?, content = ?, status = ?, categories = ?, tags = ?,
@@ -610,24 +799,15 @@ def edit_post(id):
610
  featured_image = ?, publish_date = ?
611
  WHERE id = ?
612
  ''', (
613
- request.form['post-title'],
614
- request.form['post-slug'],
615
- request.form['post-content'],
616
- request.form.get('post-status', 'draft'),
617
- ','.join(request.form.getlist('post-categories')),
618
- request.form.get('post-tags', ''),
619
- request.form.get('post-excerpt', ''),
620
- request.form.get('post-seo-title', ''),
621
- request.form.get('post-seo-description', ''),
622
- request.form.get('post-seo-keywords', ''),
623
- request.form.get('post-featured-image', ''),
624
- request.form.get('post-publish-date', ''),
625
  id
626
  ))
627
  conn.commit()
628
  update_db_to_huggingface()
629
  conn.close()
630
- return redirect(url_for('cms'))
 
631
 
632
  conn.close()
633
  return render_template('cms.html', section='post-editor-section', post=post, cases=cases, pages=pages, posts=posts)
@@ -642,9 +822,117 @@ def delete_post(id):
642
  conn.commit()
643
  update_db_to_huggingface()
644
  conn.close()
645
- return redirect(url_for('cms'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
 
647
- # Các route khác giữ nguyên từ mã hiện tại
648
  @app.route('/test')
649
  def test():
650
  return "Server is running!"
@@ -825,85 +1113,6 @@ def hanhtrinhkh(case_id):
825
  conn.close()
826
  return render_template('hanhtrinhkh.html', case=case, milestones=milestones, doctor=doctor)
827
 
828
- @app.route('/cms/team')
829
- @auth.login_required
830
- def cms_team():
831
- conn = get_db_connection()
832
- cursor = conn.cursor()
833
- cursor.execute('SELECT * FROM team')
834
- team = [dict(row) for row in cursor.fetchall()]
835
- conn.close()
836
- return render_template('cms.html', section='team-section', team=team)
837
-
838
- @app.route('/cms/team/new', methods=['GET', 'POST'])
839
- @auth.login_required
840
- def add_team_member():
841
- conn = get_db_connection()
842
- cursor = conn.cursor()
843
- if request.method == 'POST':
844
- cursor.execute('''
845
- INSERT INTO team (name, specialty, photo, description, facebook_url, linkedin_url, instagram_url)
846
- VALUES (?, ?, ?, ?, ?, ?, ?)
847
- ''', (
848
- request.form['name'],
849
- request.form['specialty'],
850
- request.form.get('photo', ''),
851
- request.form.get('description', ''),
852
- request.form.get('facebook_url', '#'),
853
- request.form.get('linkedin_url', '#'),
854
- request.form.get('instagram_url', '#')
855
- ))
856
- conn.commit()
857
- update_db_to_huggingface()
858
- conn.close()
859
- return redirect(url_for('cms_team'))
860
- conn.close()
861
- return render_template('cms.html', section='team-editor-section', member=None)
862
-
863
- @app.route('/cms/team/edit/<int:id>', methods=['GET', 'POST'])
864
- @auth.login_required
865
- def edit_team_member(id):
866
- conn = get_db_connection()
867
- cursor = conn.cursor()
868
- cursor.execute('SELECT * FROM team WHERE id = ?', (id,))
869
- member = cursor.fetchone()
870
- if not member:
871
- conn.close()
872
- return "Team member not found", 404
873
- member = dict(member)
874
- if request.method == 'POST':
875
- cursor.execute('''
876
- UPDATE team
877
- SET name = ?, specialty = ?, photo = ?, description = ?, facebook_url = ?, linkedin_url = ?, instagram_url = ?
878
- WHERE id = ?
879
- ''', (
880
- request.form['name'],
881
- request.form['specialty'],
882
- request.form.get('photo', ''),
883
- request.form.get('description', ''),
884
- request.form.get('facebook_url', '#'),
885
- request.form.get('linkedin_url', '#'),
886
- request.form.get('instagram_url', '#'),
887
- id
888
- ))
889
- conn.commit()
890
- update_db_to_huggingface()
891
- conn.close()
892
- return redirect(url_for('cms_team'))
893
- conn.close()
894
- return render_template('cms.html', section='team-editor-section', member=member)
895
-
896
- @app.route('/cms/team/delete/<int:id>')
897
- @auth.login_required
898
- def delete_team_member(id):
899
- conn = get_db_connection()
900
- cursor = conn.cursor()
901
- cursor.execute('DELETE FROM team WHERE id = ?', (id,))
902
- conn.commit()
903
- update_db_to_huggingface()
904
- conn.close()
905
- return redirect(url_for('cms_team'))
906
-
907
  @app.errorhandler(401)
908
  def unauthorized(e):
909
  return "Unauthorized - Vui lòng đăng nhập", 401
 
4
  from flask import Flask, render_template, request, redirect, url_for, abort, flash, jsonify
5
  from flask_httpauth import HTTPBasicAuth
6
  from werkzeug.security import generate_password_hash, check_password_hash
7
+ from werkzeug.utils import secure_filename
8
+ from huggingface_hub import hf_hub_download, upload_file
9
  import logging
10
  import tempfile
11
  import fcntl
 
13
 
14
  app = Flask(__name__)
15
  app.config['SECRET_KEY'] = os.getenv("FLASK_SECRET_KEY", "your-secret-key-here")
16
+ app.config['UPLOAD_FOLDER'] = 'static/uploads'
17
  auth = HTTPBasicAuth()
18
 
19
  # Thiết lập logging
20
  logging.basicConfig(level=logging.INFO)
21
  logger = logging.getLogger(__name__)
22
 
23
+ # Đảm bảo thư mục upload tồn tại
24
+ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
25
+
26
  # Cấu hình người dùng
27
  ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin")
28
  ADMIN_PASSWORD_HASH = generate_password_hash(os.getenv("ADMIN_PASSWORD", "password"))
 
120
  CREATE TABLE IF NOT EXISTS case_studies (
121
  id INTEGER PRIMARY KEY AUTOINCREMENT,
122
  title TEXT NOT NULL,
123
+ treatment TEXT NOT NULL,
124
  description TEXT,
125
  before_image TEXT,
126
  after_image TEXT,
 
129
  patient_rating TEXT DEFAULT '5',
130
  patient_avatar TEXT,
131
  status TEXT DEFAULT 'draft',
132
+ date TEXT NOT NULL,
133
  duration TEXT,
134
  visits TEXT,
135
+ case_id TEXT NOT NULL UNIQUE,
136
  seo_title TEXT,
137
  seo_description TEXT,
138
  seo_keywords TEXT,
 
155
  CREATE TABLE IF NOT EXISTS pages (
156
  id INTEGER PRIMARY KEY AUTOINCREMENT,
157
  title TEXT NOT NULL,
158
+ slug TEXT NOT NULL UNIQUE,
159
  content TEXT,
160
  status TEXT DEFAULT 'draft',
161
  template TEXT DEFAULT 'default',
 
182
  CREATE TABLE IF NOT EXISTS posts (
183
  id INTEGER PRIMARY KEY AUTOINCREMENT,
184
  title TEXT NOT NULL,
185
+ slug TEXT NOT NULL UNIQUE,
186
  content TEXT,
187
  status TEXT DEFAULT 'draft',
188
  categories TEXT,
 
204
  ('10 Dental Care Tips', 'dental-care-tips', '<p>Learn how to maintain a healthy smile with these tips...</p>', 'published', 'Dental Care', 'teeth,care', 'Top 10 dental care tips for a healthy smile.', 'Dental Care Tips', 'Learn dental care tips.', 'dental,care,tips', 'https://images.unsplash.com/photo-1588776814546-1ffcf47267a5', '2025-04-28')
205
  ''')
206
 
207
+ # Tạo các bảng khác
208
  cursor.execute('''
209
  CREATE TABLE IF NOT EXISTS our_story (
210
  id INTEGER PRIMARY KEY AUTOINCREMENT,
 
299
  FOREIGN KEY (case_id) REFERENCES case_studies(id)
300
  )
301
  ''')
302
+ cursor.execute('''
303
+ CREATE TABLE IF NOT EXISTS comments (
304
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
305
+ post_id INTEGER NOT NULL,
306
+ author_name TEXT NOT NULL,
307
+ author_email TEXT NOT NULL,
308
+ content TEXT NOT NULL,
309
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
310
+ FOREIGN KEY (post_id) REFERENCES posts(id)
311
+ )
312
+ ''')
313
  cursor.execute('CREATE INDEX IF NOT EXISTS idx_pjm_case_id ON patient_journey_milestones(case_id)')
314
 
315
  conn.commit()
 
345
  posts = [dict(row) for row in cursor.fetchall()]
346
 
347
  if request.method == 'POST':
348
+ # Lấy dữ liệu từ form
349
+ title = request.form.get('case-title')
350
+ treatment = request.form.get('case-treatment')
351
+ description = request.form.get('case-description')
352
+ status = request.form.get('case-status', 'draft')
353
+ date = request.form.get('case-date')
354
+ category = request.form.get('case-category')
355
+ patient_name = request.form.get('case-patient-name', '')
356
+ patient_age = request.form.get('case-patient-age', '')
357
+ patient_rating = request.form.get('case-patient-rating', '5')
358
+ duration = request.form.get('case-duration', '')
359
+ visits = request.form.get('case-visits', '')
360
+ case_id = request.form.get('case-id')
361
+ seo_title = request.form.get('case-seo-title', '')
362
+ seo_description = request.form.get('case-seo-description', '')
363
+ seo_keywords = request.form.get('case-seo-keywords', '')
364
+
365
+ # Kiểm tra các trường bắt buộc
366
+ if not all([title, treatment, case_id, date]):
367
+ flash('Vui lòng điền đầy đủ các trường bắt buộc.', 'error')
368
+ conn.close()
369
+ return render_template('cms.html', section='case-editor-section', case=None, cases=cases, pages=pages, posts=posts)
370
+
371
+ # Kiểm tra case_id duy nhất
372
+ cursor.execute('SELECT id FROM case_studies WHERE case_id = ?', (case_id,))
373
+ if cursor.fetchone():
374
+ flash('Case ID đã tồn tại. Vui lòng chọn ID khác.', 'error')
375
+ conn.close()
376
+ return render_template('cms.html', section='case-editor-section', case=None, cases=cases, pages=pages, posts=posts)
377
+
378
+ # Xử lý upload hình ảnh
379
+ before_image_path = ''
380
+ if 'case-before-image' in request.files and request.files['case-before-image'].filename:
381
+ before_image = request.files['case-before-image']
382
+ filename = secure_filename(before_image.filename)
383
+ before_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
384
+ before_image_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
385
+
386
+ after_image_path = ''
387
+ if 'case-after-image' in request.files and request.files['case-after-image'].filename:
388
+ after_image = request.files['case-after-image']
389
+ filename = secure_filename(after_image.filename)
390
+ after_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
391
+ after_image_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
392
+
393
+ patient_avatar_path = ''
394
+ if 'case-patient-avatar' in request.files and request.files['case-patient-avatar'].filename:
395
+ patient_avatar = request.files['case-patient-avatar']
396
+ filename = secure_filename(patient_avatar.filename)
397
+ patient_avatar.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
398
+ patient_avatar_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
399
+
400
+ # Chèn dữ liệu vào database
401
  cursor.execute('''
402
  INSERT INTO case_studies (
403
  title, treatment, description, before_image, after_image,
404
  patient_name, patient_age, patient_rating, patient_avatar,
405
  status, date, duration, visits, case_id,
406
+ seo_title, seo_description, seo_keywords, category
407
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
408
  ''', (
409
+ title, treatment, description, before_image_path, after_image_path,
410
+ patient_name, patient_age, patient_rating, patient_avatar_path,
411
+ status, date, duration, visits, case_id,
412
+ seo_title, seo_description, seo_keywords, category
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  ))
414
  conn.commit()
415
  update_db_to_huggingface()
416
  conn.close()
417
+ flash('Case study đã được thêm thành công!', 'success')
418
+ return redirect(url_for('cms', section='cases-section'))
419
 
420
  conn.close()
421
  return render_template('cms.html', section='case-editor-section', case=None, cases=cases, pages=pages, posts=posts)
 
442
  case = dict(case)
443
 
444
  if request.method == 'POST':
445
+ # Lấy dữ liệu từ form
446
+ title = request.form.get('case-title')
447
+ treatment = request.form.get('case-treatment')
448
+ description = request.form.get('case-description')
449
+ status = request.form.get('case-status', 'draft')
450
+ date = request.form.get('case-date')
451
+ category = request.form.get('case-category')
452
+ patient_name = request.form.get('case-patient-name', '')
453
+ patient_age = request.form.get('case-patient-age', '')
454
+ patient_rating = request.form.get('case-patient-rating', '5')
455
+ duration = request.form.get('case-duration', '')
456
+ visits = request.form.get('case-visits', '')
457
+ case_id = request.form.get('case-id')
458
+ seo_title = request.form.get('case-seo-title', '')
459
+ seo_description = request.form.get('case-seo-description', '')
460
+ seo_keywords = request.form.get('case-seo-keywords', '')
461
+
462
+ # Kiểm tra các trường bắt buộc
463
+ if not all([title, treatment, case_id, date]):
464
+ flash('Vui lòng điền đầy đủ các trường bắt buộc.', 'error')
465
+ conn.close()
466
+ return render_template('cms.html', section='case-editor-section', case=case, cases=cases, pages=pages, posts=posts)
467
+
468
+ # Kiểm tra case_id duy nhất (ngoại trừ case hiện tại)
469
+ cursor.execute('SELECT id FROM case_studies WHERE case_id = ? AND id != ?', (case_id, id))
470
+ if cursor.fetchone():
471
+ flash('Case ID đã tồn tại. Vui lòng chọn ID khác.', 'error')
472
+ conn.close()
473
+ return render_template('cms.html', section='case-editor-section', case=case, cases=cases, pages=pages, posts=posts)
474
+
475
+ # Xử lý upload hình ảnh
476
+ before_image_path = case['before_image']
477
+ if 'case-before-image' in request.files and request.files['case-before-image'].filename:
478
+ before_image = request.files['case-before-image']
479
+ filename = secure_filename(before_image.filename)
480
+ before_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
481
+ before_image_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
482
+
483
+ after_image_path = case['after_image']
484
+ if 'case-after-image' in request.files and request.files['case-after-image'].filename:
485
+ after_image = request.files['case-after-image']
486
+ filename = secure_filename(after_image.filename)
487
+ after_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
488
+ after_image_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
489
+
490
+ patient_avatar_path = case['patient_avatar']
491
+ if 'case-patient-avatar' in request.files and request.files['case-patient-avatar'].filename:
492
+ patient_avatar = request.files['case-patient-avatar']
493
+ filename = secure_filename(patient_avatar.filename)
494
+ patient_avatar.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
495
+ patient_avatar_path = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
496
+
497
+ # Cập nhật dữ liệu trong database
498
  cursor.execute('''
499
  UPDATE case_studies
500
  SET title = ?, treatment = ?, description = ?, before_image = ?, after_image = ?,
501
  patient_name = ?, patient_age = ?, patient_rating = ?, patient_avatar = ?,
502
  status = ?, date = ?, duration = ?, visits = ?, case_id = ?,
503
+ seo_title = ?, seo_description = ?, seo_keywords = ?, category = ?
504
  WHERE id = ?
505
  ''', (
506
+ title, treatment, description, before_image_path, after_image_path,
507
+ patient_name, patient_age, patient_rating, patient_avatar_path,
508
+ status, date, duration, visits, case_id,
509
+ seo_title, seo_description, seo_keywords, category,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
  id
511
  ))
512
  conn.commit()
513
  update_db_to_huggingface()
514
  conn.close()
515
+ flash('Case study đã được cập nhật thành công!', 'success')
516
+ return redirect(url_for('cms', section='cases-section'))
517
 
518
  conn.close()
519
  return render_template('cms.html', section='case-editor-section', case=case, cases=cases, pages=pages, posts=posts)
 
528
  conn.commit()
529
  update_db_to_huggingface()
530
  conn.close()
531
+ flash('Case study đã được xóa thành công!', 'success')
532
+ return redirect(url_for('cms', section='cases-section'))
533
 
534
  # Route để thêm page mới
535
  @app.route('/cms/pages/new', methods=['GET', 'POST'])
 
546
  posts = [dict(row) for row in cursor.fetchall()]
547
 
548
  if request.method == 'POST':
549
+ title = request.form.get('page-title')
550
+ slug = request.form.get('page-slug')
551
+ content = request.form.get('page-content')
552
+ status = request.form.get('page-status', 'draft')
553
+ template = request.form.get('page-template', 'default')
554
+ parent_id = request.form.get('page-parent', 0, type=int)
555
+ seo_title = request.form.get('seo-title', '')
556
+ seo_description = request.form.get('seo-description', '')
557
+ seo_keywords = request.form.get('seo-keywords', '')
558
+ featured_image = ''
559
+
560
+ if 'page-featured-image' in request.files and request.files['page-featured-image'].filename:
561
+ featured_image_file = request.files['page-featured-image']
562
+ filename = secure_filename(featured_image_file.filename)
563
+ featured_image_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
564
+ featured_image = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
565
+
566
+ if not all([title, slug]):
567
+ flash('Vui lòng điền đầy đủ tiêu đề và slug.', 'error')
568
+ conn.close()
569
+ return render_template('cms.html', section='page-editor-section', page=None, cases=cases, pages=pages, posts=posts)
570
+
571
+ cursor.execute('SELECT id FROM pages WHERE slug = ?', (slug,))
572
+ if cursor.fetchone():
573
+ flash('Slug đã tồn tại. Vui lòng chọn slug khác.', 'error')
574
+ conn.close()
575
+ return render_template('cms.html', section='page-editor-section', page=None, cases=cases, pages=pages, posts=posts)
576
+
577
  cursor.execute('''
578
  INSERT INTO pages (
579
  title, slug, content, status, template, parent_id,
580
  seo_title, seo_description, seo_keywords, featured_image, last_modified
581
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
582
  ''', (
583
+ title, slug, content, status, template, parent_id,
584
+ seo_title, seo_description, seo_keywords, featured_image,
 
 
 
 
 
 
 
 
585
  datetime.now().strftime('%Y-%m-%d %H:%M:%S')
586
  ))
587
  conn.commit()
588
  update_db_to_huggingface()
589
  conn.close()
590
+ flash('Page đã được thêm thành công!', 'success')
591
+ return redirect(url_for('cms', section='pages-section'))
592
 
593
  conn.close()
594
  return render_template('cms.html', section='page-editor-section', page=None, cases=cases, pages=pages, posts=posts)
 
615
  page = dict(page)
616
 
617
  if request.method == 'POST':
618
+ title = request.form.get('page-title')
619
+ slug = request.form.get('page-slug')
620
+ content = request.form.get('page-content')
621
+ status = request.form.get('page-status', 'draft')
622
+ template = request.form.get('page-template', 'default')
623
+ parent_id = request.form.get('page-parent', 0, type=int)
624
+ seo_title = request.form.get('seo-title', '')
625
+ seo_description = request.form.get('seo-description', '')
626
+ seo_keywords = request.form.get('seo-keywords', '')
627
+ featured_image = page['featured_image']
628
+
629
+ if 'page-featured-image' in request.files and request.files['page-featured-image'].filename:
630
+ featured_image_file = request.files['page-featured-image']
631
+ filename = secure_filename(featured_image_file.filename)
632
+ featured_image_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
633
+ featured_image = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
634
+
635
+ if not all([title, slug]):
636
+ flash('Vui lòng điền đầy đủ tiêu đề và slug.', 'error')
637
+ conn.close()
638
+ return render_template('cms.html', section='page-editor-section', page=page, cases=cases, pages=pages, posts=posts)
639
+
640
+ cursor.execute('SELECT id FROM pages WHERE slug = ? AND id != ?', (slug, id))
641
+ if cursor.fetchone():
642
+ flash('Slug đã tồn tại. Vui lòng chọn slug khác.', 'error')
643
+ conn.close()
644
+ return render_template('cms.html', section='page-editor-section', page=page, cases=cases, pages=pages, posts=posts)
645
+
646
  cursor.execute('''
647
  UPDATE pages
648
  SET title = ?, slug = ?, content = ?, status = ?, template = ?, parent_id = ?,
 
650
  last_modified = ?
651
  WHERE id = ?
652
  ''', (
653
+ title, slug, content, status, template, parent_id,
654
+ seo_title, seo_description, seo_keywords, featured_image,
 
 
 
 
 
 
 
 
655
  datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
656
  id
657
  ))
658
  conn.commit()
659
  update_db_to_huggingface()
660
  conn.close()
661
+ flash('Page đã được cập nhật thành công!', 'success')
662
+ return redirect(url_for('cms', section='pages-section'))
663
 
664
  conn.close()
665
  return render_template('cms.html', section='page-editor-section', page=page, cases=cases, pages=pages, posts=posts)
 
674
  conn.commit()
675
  update_db_to_huggingface()
676
  conn.close()
677
+ flash('Page đã được xóa thành công!', 'success')
678
+ return redirect(url_for('cms', section='pages-section'))
679
 
680
  # Route để thêm post mới
681
  @app.route('/cms/posts/new', methods=['GET', 'POST'])
 
692
  posts = [dict(row) for row in cursor.fetchall()]
693
 
694
  if request.method == 'POST':
695
+ title = request.form.get('post-title')
696
+ slug = request.form.get('post-slug')
697
+ content = request.form.get('post-content')
698
+ status = request.form.get('post-status', 'draft')
699
+ categories = ','.join(request.form.getlist('post-categories'))
700
+ tags = request.form.get('post-tags', '')
701
+ excerpt = request.form.get('post-excerpt', '')
702
+ seo_title = request.form.get('post-seo-title', '')
703
+ seo_description = request.form.get('post-seo-description', '')
704
+ seo_keywords = request.form.get('post-seo-keywords', '')
705
+ publish_date = request.form.get('post-publish-date', '')
706
+ featured_image = ''
707
+
708
+ if 'post-featured-image' in request.files and request.files['post-featured-image'].filename:
709
+ featured_image_file = request.files['post-featured-image']
710
+ filename = secure_filename(featured_image_file.filename)
711
+ featured_image_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
712
+ featured_image = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
713
+
714
+ if not all([title, slug]):
715
+ flash('Vui lòng điền đầy đủ tiêu đề và slug.', 'error')
716
+ conn.close()
717
+ return render_template('cms.html', section='post-editor-section', post=None, cases=cases, pages=pages, posts=posts)
718
+
719
+ cursor.execute('SELECT id FROM posts WHERE slug = ?', (slug,))
720
+ if cursor.fetchone():
721
+ flash('Slug đã tồn tại. Vui lòng chọn slug khác.', 'error')
722
+ conn.close()
723
+ return render_template('cms.html', section='post-editor-section', post=None, cases=cases, pages=pages, posts=posts)
724
+
725
  cursor.execute('''
726
  INSERT INTO posts (
727
  title, slug, content, status, categories, tags, excerpt,
728
  seo_title, seo_description, seo_keywords, featured_image, publish_date
729
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
730
  ''', (
731
+ title, slug, content, status, categories, tags, excerpt,
732
+ seo_title, seo_description, seo_keywords, featured_image, publish_date
 
 
 
 
 
 
 
 
 
 
733
  ))
734
  conn.commit()
735
  update_db_to_huggingface()
736
  conn.close()
737
+ flash('Post đã được thêm thành công!', 'success')
738
+ return redirect(url_for('cms', section='posts-section'))
739
 
740
  conn.close()
741
  return render_template('cms.html', section='post-editor-section', post=None, cases=cases, pages=pages, posts=posts)
 
762
  post = dict(post)
763
 
764
  if request.method == 'POST':
765
+ title = request.form.get('post-title')
766
+ slug = request.form.get('post-slug')
767
+ content = request.form.get('post-content')
768
+ status = request.form.get('post-status', 'draft')
769
+ categories = ','.join(request.form.getlist('post-categories'))
770
+ tags = request.form.get('post-tags', '')
771
+ excerpt = request.form.get('post-excerpt', '')
772
+ seo_title = request.form.get('post-seo-title', '')
773
+ seo_description = request.form.get('post-seo-description', '')
774
+ seo_keywords = request.form.get('post-seo-keywords', '')
775
+ publish_date = request.form.get('post-publish-date', '')
776
+ featured_image = post['featured_image']
777
+
778
+ if 'post-featured-image' in request.files and request.files['post-featured-image'].filename:
779
+ featured_image_file = request.files['post-featured-image']
780
+ filename = secure_filename(featured_image_file.filename)
781
+ featured_image_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
782
+ featured_image = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
783
+
784
+ if not all([title, slug]):
785
+ flash('Vui lòng điền đầy đủ tiêu đề và slug.', 'error')
786
+ conn.close()
787
+ return render_template('cms.html', section='post-editor-section', post=post, cases=cases, pages=pages, posts=posts)
788
+
789
+ cursor.execute('SELECT id FROM posts WHERE slug = ? AND id != ?', (slug, id))
790
+ if cursor.fetchone():
791
+ flash('Slug đã tồn tại. Vui lòng chọn slug khác.', 'error')
792
+ conn.close()
793
+ return render_template('cms.html', section='post-editor-section', post=post, cases=cases, pages=pages, posts=posts)
794
+
795
  cursor.execute('''
796
  UPDATE posts
797
  SET title = ?, slug = ?, content = ?, status = ?, categories = ?, tags = ?,
 
799
  featured_image = ?, publish_date = ?
800
  WHERE id = ?
801
  ''', (
802
+ title, slug, content, status, categories, tags, excerpt,
803
+ seo_title, seo_description, seo_keywords, featured_image, publish_date,
 
 
 
 
 
 
 
 
 
 
804
  id
805
  ))
806
  conn.commit()
807
  update_db_to_huggingface()
808
  conn.close()
809
+ flash('Post đã được cập nhật thành công!', 'success')
810
+ return redirect(url_for('cms', section='posts-section'))
811
 
812
  conn.close()
813
  return render_template('cms.html', section='post-editor-section', post=post, cases=cases, pages=pages, posts=posts)
 
822
  conn.commit()
823
  update_db_to_huggingface()
824
  conn.close()
825
+ flash('Post đã được xóa thành công!', 'success')
826
+ return redirect(url_for('cms', section='posts-section'))
827
+
828
+ # Route để quản lý team
829
+ @app.route('/cms/team')
830
+ @auth.login_required
831
+ def cms_team():
832
+ conn = get_db_connection()
833
+ cursor = conn.cursor()
834
+ cursor.execute('SELECT * FROM team')
835
+ team = [dict(row) for row in cursor.fetchall()]
836
+ conn.close()
837
+ return render_template('cms.html', section='team-section', team=team)
838
+
839
+ @app.route('/cms/team/new', methods=['GET', 'POST'])
840
+ @auth.login_required
841
+ def add_team_member():
842
+ conn = get_db_connection()
843
+ cursor = conn.cursor()
844
+ if request.method == 'POST':
845
+ name = request.form.get('name')
846
+ specialty = request.form.get('specialty')
847
+ description = request.form.get('description', '')
848
+ facebook_url = request.form.get('facebook_url', '#')
849
+ linkedin_url = request.form.get('linkedin_url', '#')
850
+ instagram_url = request.form.get('instagram_url', '#')
851
+ photo = ''
852
+
853
+ if 'photo' in request.files and request.files['photo'].filename:
854
+ photo_file = request.files['photo']
855
+ filename = secure_filename(photo_file.filename)
856
+ photo_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
857
+ photo = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
858
+
859
+ if not all([name, specialty]):
860
+ flash('Vui lòng điền đầy đủ tên và chuyên môn.', 'error')
861
+ conn.close()
862
+ return render_template('cms.html', section='team-editor-section', member=None)
863
+
864
+ cursor.execute('''
865
+ INSERT INTO team (name, specialty, photo, description, facebook_url, linkedin_url, instagram_url)
866
+ VALUES (?, ?, ?, ?, ?, ?, ?)
867
+ ''', (name, specialty, photo, description, facebook_url, linkedin_url, instagram_url))
868
+ conn.commit()
869
+ update_db_to_huggingface()
870
+ conn.close()
871
+ flash('Thành viên đã được thêm thành công!', 'success')
872
+ return redirect(url_for('cms_team'))
873
+
874
+ conn.close()
875
+ return render_template('cms.html', section='team-editor-section', member=None)
876
+
877
+ @app.route('/cms/team/edit/<int:id>', methods=['GET', 'POST'])
878
+ @auth.login_required
879
+ def edit_team_member(id):
880
+ conn = get_db_connection()
881
+ cursor = conn.cursor()
882
+ cursor.execute('SELECT * FROM team WHERE id = ?', (id,))
883
+ member = cursor.fetchone()
884
+ if not member:
885
+ conn.close()
886
+ return "Team member not found", 404
887
+ member = dict(member)
888
+
889
+ if request.method == 'POST':
890
+ name = request.form.get('name')
891
+ specialty = request.form.get('specialty')
892
+ description = request.form.get('description', '')
893
+ facebook_url = request.form.get('facebook_url', '#')
894
+ linkedin_url = request.form.get('linkedin_url', '#')
895
+ instagram_url = request.form.get('instagram_url', '#')
896
+ photo = member['photo']
897
+
898
+ if 'photo' in request.files and request.files['photo'].filename:
899
+ photo_file = request.files['photo']
900
+ filename = secure_filename(photo_file.filename)
901
+ photo_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
902
+ photo = f"/{app.config['UPLOAD_FOLDER']}/{filename}"
903
+
904
+ if not all([name, specialty]):
905
+ flash('Vui lòng điền đầy đủ tên và chuyên môn.', 'error')
906
+ conn.close()
907
+ return render_template('cms.html', section='team-editor-section', member=member)
908
+
909
+ cursor.execute('''
910
+ UPDATE team
911
+ SET name = ?, specialty = ?, photo = ?, description = ?, facebook_url = ?, linkedin_url = ?, instagram_url = ?
912
+ WHERE id = ?
913
+ ''', (name, specialty, photo, description, facebook_url, linkedin_url, instagram_url, id))
914
+ conn.commit()
915
+ update_db_to_huggingface()
916
+ conn.close()
917
+ flash('Thành viên đã được cập nhật thành công!', 'success')
918
+ return redirect(url_for('cms_team'))
919
+
920
+ conn.close()
921
+ return render_template('cms.html', section='team-editor-section', member=member)
922
+
923
+ @app.route('/cms/team/delete/<int:id>')
924
+ @auth.login_required
925
+ def delete_team_member(id):
926
+ conn = get_db_connection()
927
+ cursor = conn.cursor()
928
+ cursor.execute('DELETE FROM team WHERE id = ?', (id,))
929
+ conn.commit()
930
+ update_db_to_huggingface()
931
+ conn.close()
932
+ flash('Thành viên đã được xóa thành công!', 'success')
933
+ return redirect(url_for('cms_team'))
934
 
935
+ # Các route công khai
936
  @app.route('/test')
937
  def test():
938
  return "Server is running!"
 
1113
  conn.close()
1114
  return render_template('hanhtrinhkh.html', case=case, milestones=milestones, doctor=doctor)
1115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1116
  @app.errorhandler(401)
1117
  def unauthorized(e):
1118
  return "Unauthorized - Vui lòng đăng nhập", 401