noranisa commited on
Commit
6b93641
·
verified ·
1 Parent(s): 2afaaa9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -33
app.py CHANGED
@@ -11,14 +11,19 @@ from flask_admin.contrib.sqla import ModelView
11
 
12
  # --- KONFIGURASI APLIKASI ---
13
  app = Flask(__name__)
14
- # Mengambil SECRET_KEY dari Hugging Face Secrets, dengan nilai default untuk development lokal
15
  app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-super-secret-key-for-local-dev')
16
 
17
 
18
  # --- KONFIGURASI DATABASE ---
19
- # Menentukan path absolut untuk file database agar tidak ada masalah path
20
- basedir = os.path.abspath(os.path.dirname(__file__))
21
- app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'database.db')
 
 
 
 
 
 
22
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
23
  db = SQLAlchemy(app)
24
 
@@ -36,29 +41,23 @@ class Product(db.Model):
36
 
37
 
38
  # --- INISIALISASI DATABASE OTOMATIS ---
39
- # Kode ini akan dijalankan saat aplikasi pertama kali dimulai.
40
- # Ia akan membuat file database.db dan tabel di dalamnya jika belum ada.
41
- # Ini menyelesaikan masalah "unable to open database file" di Hugging Face.
42
  with app.app_context():
43
  db.create_all()
44
 
45
 
46
  # --- FUNGSI KEAMANAN UNTUK ADMIN PANEL ---
47
  def check_auth(username, password):
48
- """Fungsi untuk memeriksa username & password admin dari Hugging Face Secrets."""
49
- ADMIN_USER = os.environ.get('ADMIN_USER', 'admin') # Default 'admin'
50
- ADMIN_PASS = os.environ.get('ADMIN_PASS', 'password') # Default 'password'
51
  return username == ADMIN_USER and password == ADMIN_PASS
52
 
53
  def authenticate():
54
- """Mengirim respons 401 Unauthorized jika login gagal."""
55
  return Response(
56
  'Could not verify your access level for that URL.\n'
57
  'You have to login with proper credentials', 401,
58
  {'WWW-Authenticate': 'Basic realm="Login Required"'})
59
 
60
  def protected(f):
61
- """Decorator untuk melindungi sebuah route."""
62
  @wraps(f)
63
  def decorated(*args, **kwargs):
64
  auth = request.authorization
@@ -69,7 +68,6 @@ def protected(f):
69
 
70
 
71
  # --- PENGATURAN ADMIN PANEL ---
72
- # Membuat view admin yang aman menggunakan decorator 'protected'
73
  class SecureAdminIndexView(AdminIndexView):
74
  @protected
75
  def dispatch_request(self, *args, **kwargs):
@@ -80,29 +78,18 @@ class SecureModelView(ModelView):
80
  def dispatch_request(self, *args, **kwargs):
81
  return super(SecureModelView, self).dispatch_request(*args, **kwargs)
82
 
83
- # Inisialisasi admin panel
84
  admin = Admin(app, name='Bit & Bean Admin', template_mode='bootstrap4', index_view=SecureAdminIndexView())
85
- # Menambahkan model 'Product' ke admin panel agar bisa dikelola
86
  admin.add_view(SecureModelView(Product, db.session))
87
 
88
 
89
  # --- FUNGSI QR CODE ---
90
  def generate_qr_code(data):
91
- """Fungsi untuk membuat QR code dan mengembalikannya sebagai string base64."""
92
- qr = qrcode.QRCode(
93
- version=1,
94
- error_correction=qrcode.constants.ERROR_CORRECT_L,
95
- box_size=10,
96
- border=4,
97
- )
98
  qr.add_data(data)
99
  qr.make(fit=True)
100
-
101
  img = qr.make_image(fill_color="black", back_color="white")
102
-
103
  buffered = io.BytesIO()
104
  img.save(buffered, format="PNG")
105
-
106
  img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
107
  return img_str
108
 
@@ -110,16 +97,10 @@ def generate_qr_code(data):
110
  # --- ROUTE UNTUK HALAMAN UTAMA ---
111
  @app.route('/')
112
  def home():
113
- """Mengambil data produk dari database dan menampilkannya di halaman utama."""
114
  products_from_db = Product.query.all()
115
-
116
  products_with_qr = []
117
  for product in products_from_db:
118
- # !! PENTING: Ganti URL ini dengan URL Hugging Face Space Anda !!
119
- # Contoh: https://namaanda-bitbean.hf.space/product/1
120
- product_url = f"https://your-space-url.hf.space/product/{product.id}"
121
-
122
- # Konversi objek database menjadi dictionary agar mudah diolah di template
123
  product_data = {
124
  "id": product.id,
125
  "name": product.name,
@@ -129,5 +110,4 @@ def home():
129
  "qr_code": generate_qr_code(product_url)
130
  }
131
  products_with_qr.append(product_data)
132
-
133
  return render_template('index.html', products=products_with_qr)
 
11
 
12
  # --- KONFIGURASI APLIKASI ---
13
  app = Flask(__name__)
 
14
  app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-super-secret-key-for-local-dev')
15
 
16
 
17
  # --- KONFIGURASI DATABASE ---
18
+ # Di Hugging Face, direktori root aplikasi bersifat read-only.
19
+ # Kita harus menyimpan file database di direktori yang bisa ditulis, seperti /data.
20
+ DATA_DIR = '/data'
21
+ # Pastikan direktori /data ada, buat jika belum ada.
22
+ os.makedirs(DATA_DIR, exist_ok=True)
23
+
24
+ # Tentukan path lengkap ke file database di dalam direktori /data
25
+ db_path = os.path.join(DATA_DIR, 'database.db')
26
+ app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}'
27
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
28
  db = SQLAlchemy(app)
29
 
 
41
 
42
 
43
  # --- INISIALISASI DATABASE OTOMATIS ---
 
 
 
44
  with app.app_context():
45
  db.create_all()
46
 
47
 
48
  # --- FUNGSI KEAMANAN UNTUK ADMIN PANEL ---
49
  def check_auth(username, password):
50
+ ADMIN_USER = os.environ.get('ADMIN_USER', 'admin')
51
+ ADMIN_PASS = os.environ.get('ADMIN_PASS', 'password')
 
52
  return username == ADMIN_USER and password == ADMIN_PASS
53
 
54
  def authenticate():
 
55
  return Response(
56
  'Could not verify your access level for that URL.\n'
57
  'You have to login with proper credentials', 401,
58
  {'WWW-Authenticate': 'Basic realm="Login Required"'})
59
 
60
  def protected(f):
 
61
  @wraps(f)
62
  def decorated(*args, **kwargs):
63
  auth = request.authorization
 
68
 
69
 
70
  # --- PENGATURAN ADMIN PANEL ---
 
71
  class SecureAdminIndexView(AdminIndexView):
72
  @protected
73
  def dispatch_request(self, *args, **kwargs):
 
78
  def dispatch_request(self, *args, **kwargs):
79
  return super(SecureModelView, self).dispatch_request(*args, **kwargs)
80
 
 
81
  admin = Admin(app, name='Bit & Bean Admin', template_mode='bootstrap4', index_view=SecureAdminIndexView())
 
82
  admin.add_view(SecureModelView(Product, db.session))
83
 
84
 
85
  # --- FUNGSI QR CODE ---
86
  def generate_qr_code(data):
87
+ qr = qrcode.QRCode(version=1, box_size=10, border=4)
 
 
 
 
 
 
88
  qr.add_data(data)
89
  qr.make(fit=True)
 
90
  img = qr.make_image(fill_color="black", back_color="white")
 
91
  buffered = io.BytesIO()
92
  img.save(buffered, format="PNG")
 
93
  img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
94
  return img_str
95
 
 
97
  # --- ROUTE UNTUK HALAMAN UTAMA ---
98
  @app.route('/')
99
  def home():
 
100
  products_from_db = Product.query.all()
 
101
  products_with_qr = []
102
  for product in products_from_db:
103
+ product_url = f"https://BitBean-company.hf.space/product/{product.id}" # Sesuai URL Anda
 
 
 
 
104
  product_data = {
105
  "id": product.id,
106
  "name": product.name,
 
110
  "qr_code": generate_qr_code(product_url)
111
  }
112
  products_with_qr.append(product_data)
 
113
  return render_template('index.html', products=products_with_qr)