testdeep123 commited on
Commit
06a85d1
·
verified ·
1 Parent(s): 09a55da

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -31
app.py CHANGED
@@ -1,13 +1,15 @@
 
1
  import os, shutil, zipfile, threading, time
2
  from flask import Flask, request, render_template_string
3
  import gdown
4
  from huggingface_hub import HfApi, login, upload_folder
5
 
6
- # Environment variables (set them in HF Spaces settings)
7
  FOLDER_URL = os.getenv("FOLDER_URL")
8
  REPO_ID = os.getenv("REPO_ID")
9
  TOKEN = os.getenv("HF_TOKEN")
10
 
 
11
  DOWNLOAD_DIR = "/tmp/backups"
12
  EXTRACT_DIR = "/tmp/extracted_backups"
13
 
@@ -17,95 +19,106 @@ schedule_interval = 0
17
 
18
  app = Flask(__name__)
19
 
20
- # Backup logic
21
  def run_backup():
22
  global last_backup_time
 
23
  try:
 
 
24
  shutil.rmtree(DOWNLOAD_DIR, ignore_errors=True)
25
  shutil.rmtree(EXTRACT_DIR, ignore_errors=True)
26
  os.makedirs(DOWNLOAD_DIR, exist_ok=True)
27
  os.makedirs(EXTRACT_DIR, exist_ok=True)
 
28
 
29
- gdown.download_folder(
30
- url=FOLDER_URL,
31
- output=DOWNLOAD_DIR,
32
- use_cookies=False,
33
- quiet=False
34
- )
35
 
 
36
  for root, _, files in os.walk(DOWNLOAD_DIR):
37
  for f in files:
38
  if f.endswith(".zip"):
39
  zp = os.path.join(root, f)
40
  with zipfile.ZipFile(zp) as z:
41
  z.extractall(EXTRACT_DIR)
 
42
 
43
- bad = os.path.join(EXTRACT_DIR, "world_nither")
 
44
  good = os.path.join(EXTRACT_DIR, "world_nether")
45
  if os.path.exists(bad) and not os.path.exists(good):
46
  os.rename(bad, good)
 
47
 
 
48
  login(token=TOKEN)
49
  api = HfApi()
50
- try:
51
- api.delete_repo(repo_id=REPO_ID, repo_type="dataset")
52
- except Exception as err:
53
- print("delete skipped:", err)
54
-
55
- api.create_repo(repo_id=REPO_ID, repo_type="dataset", private=False, exist_ok=True)
56
 
 
57
  subfolders = {
58
  "world": os.path.join(EXTRACT_DIR, "world"),
59
  "world_nether": os.path.join(EXTRACT_DIR, "world_nether"),
60
  "world_the_end": os.path.join(EXTRACT_DIR, "world_the_end"),
61
  "plugins": os.path.join(EXTRACT_DIR, "plugins")
62
  }
63
-
64
  for name, path in subfolders.items():
65
  if os.path.exists(path):
 
66
  upload_folder(
67
  repo_id=REPO_ID,
68
  folder_path=path,
69
  repo_type="dataset",
70
  token=TOKEN,
71
  path_in_repo=name,
72
- commit_message="add " + name
73
  )
 
 
 
 
74
  last_backup_time = time.ctime()
75
- return "Backup completed"
76
  except Exception as e:
77
- return f"Error: {str(e)}"
 
78
 
79
- # Background timer
80
  def schedule_loop():
81
  while True:
82
  if schedule_interval > 0:
83
  run_backup()
84
  time.sleep(schedule_interval * 60)
85
  else:
86
- time.sleep(10)
87
 
88
- # Start scheduler thread
89
  threading.Thread(target=schedule_loop, daemon=True).start()
90
 
91
- # HTML template
92
- HTML = """
93
  <!DOCTYPE html>
94
  <html>
95
  <head>
96
- <title>Minecraft Backup Panel</title>
97
  <meta name="viewport" content="width=device-width, initial-scale=1">
 
98
  <style>
99
  body { font-family: sans-serif; padding: 20px; max-width: 600px; margin: auto; }
100
  h2 { font-size: 24px; }
101
- input, button { width: 100%; padding: 10px; margin: 8px 0; font-size: 16px; }
102
- .box { background: #f5f5f5; padding: 15px; border-radius: 8px; margin-top: 20px; }
103
  </style>
104
  </head>
105
  <body>
106
  <h2>Minecraft Backup Controller</h2>
107
  <form method="post">
108
- <label>Set interval (minutes)</label>
109
  <input type="number" name="interval" value="{{ interval }}" min="1">
110
  <button type="submit">Set Timer</button>
111
  </form>
@@ -115,18 +128,18 @@ HTML = """
115
  </form>
116
  <div class="box">
117
  <p><strong>Last Backup:</strong> {{ last_run }}</p>
118
- <p><strong>Status:</strong> {{ status }}</p>
119
  </div>
120
  </body>
121
  </html>
122
- """
123
 
124
  @app.route("/", methods=["GET", "POST"])
125
  def index():
126
  global schedule_interval
127
  status = ""
128
  if request.method == "POST":
129
- if "manual_run" in request.form:
130
  status = run_backup()
131
  else:
132
  try:
@@ -138,3 +151,11 @@ def index():
138
 
139
  if __name__ == "__main__":
140
  app.run(host="0.0.0.0", port=7860)
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
  import os, shutil, zipfile, threading, time
3
  from flask import Flask, request, render_template_string
4
  import gdown
5
  from huggingface_hub import HfApi, login, upload_folder
6
 
7
+ # Environment variables (set these in your Space settings)
8
  FOLDER_URL = os.getenv("FOLDER_URL")
9
  REPO_ID = os.getenv("REPO_ID")
10
  TOKEN = os.getenv("HF_TOKEN")
11
 
12
+ # Directories in writable tmp
13
  DOWNLOAD_DIR = "/tmp/backups"
14
  EXTRACT_DIR = "/tmp/extracted_backups"
15
 
 
19
 
20
  app = Flask(__name__)
21
 
22
+ # Backup logic with detailed logging
23
  def run_backup():
24
  global last_backup_time
25
+ log_entries = []
26
  try:
27
+ log_entries.append("Starting backup process...")
28
+ # Clean previous
29
  shutil.rmtree(DOWNLOAD_DIR, ignore_errors=True)
30
  shutil.rmtree(EXTRACT_DIR, ignore_errors=True)
31
  os.makedirs(DOWNLOAD_DIR, exist_ok=True)
32
  os.makedirs(EXTRACT_DIR, exist_ok=True)
33
+ log_entries.append(f"Directories reset: {DOWNLOAD_DIR}, {EXTRACT_DIR}")
34
 
35
+ # Download from Google Drive
36
+ log_entries.append(f"Downloading from: {FOLDER_URL}")
37
+ gdown.download_folder(url=FOLDER_URL, output=DOWNLOAD_DIR, use_cookies=False, quiet=True)
38
+ log_entries.append("Download complete.")
 
 
39
 
40
+ # Extract all zip files
41
  for root, _, files in os.walk(DOWNLOAD_DIR):
42
  for f in files:
43
  if f.endswith(".zip"):
44
  zp = os.path.join(root, f)
45
  with zipfile.ZipFile(zp) as z:
46
  z.extractall(EXTRACT_DIR)
47
+ log_entries.append(f"Extracted: {zp}")
48
 
49
+ # Fix potential typo folder
50
+ bad = os.path.join(EXTRACT_DIR, "world_nither")
51
  good = os.path.join(EXTRACT_DIR, "world_nether")
52
  if os.path.exists(bad) and not os.path.exists(good):
53
  os.rename(bad, good)
54
+ log_entries.append(f"Renamed folder: {bad} -> {good}")
55
 
56
+ # Authenticate and prepare dataset
57
  login(token=TOKEN)
58
  api = HfApi()
59
+ log_entries.append("Authenticated to Hugging Face.")
60
+ # Ensure dataset exists
61
+ api.create_repo(repo_id=REPO_ID, repo_type="dataset", private=False, exist_ok=True, token=TOKEN)
62
+ log_entries.append(f"Dataset ensured: {REPO_ID}")
 
 
63
 
64
+ # Upload subfolders
65
  subfolders = {
66
  "world": os.path.join(EXTRACT_DIR, "world"),
67
  "world_nether": os.path.join(EXTRACT_DIR, "world_nether"),
68
  "world_the_end": os.path.join(EXTRACT_DIR, "world_the_end"),
69
  "plugins": os.path.join(EXTRACT_DIR, "plugins")
70
  }
 
71
  for name, path in subfolders.items():
72
  if os.path.exists(path):
73
+ log_entries.append(f"Uploading folder: {name}")
74
  upload_folder(
75
  repo_id=REPO_ID,
76
  folder_path=path,
77
  repo_type="dataset",
78
  token=TOKEN,
79
  path_in_repo=name,
80
+ commit_message=f"add {name}"
81
  )
82
+ log_entries.append(f"Uploaded: {name}")
83
+ else:
84
+ log_entries.append(f"Skipped missing folder: {path}")
85
+
86
  last_backup_time = time.ctime()
87
+ log_entries.append(f"Backup completed at {last_backup_time}")
88
  except Exception as e:
89
+ log_entries.append(f"Error: {str(e)}")
90
+ return "<br>".join(log_entries)
91
 
92
+ # Background scheduler
93
  def schedule_loop():
94
  while True:
95
  if schedule_interval > 0:
96
  run_backup()
97
  time.sleep(schedule_interval * 60)
98
  else:
99
+ time.sleep(5)
100
 
 
101
  threading.Thread(target=schedule_loop, daemon=True).start()
102
 
103
+ # HTML UI template
104
+ HTML = '''
105
  <!DOCTYPE html>
106
  <html>
107
  <head>
108
+ <meta charset="utf-8">
109
  <meta name="viewport" content="width=device-width, initial-scale=1">
110
+ <title>Minecraft Backup Panel</title>
111
  <style>
112
  body { font-family: sans-serif; padding: 20px; max-width: 600px; margin: auto; }
113
  h2 { font-size: 24px; }
114
+ input, button { width: 100%; padding: 12px; margin: 8px 0; font-size: 16px; border-radius: 6px; border: 1px solid #ccc; }
115
+ .box { background: #f5f5f5; padding: 15px; border-radius: 8px; margin-top: 20px; word-wrap: break-word; }
116
  </style>
117
  </head>
118
  <body>
119
  <h2>Minecraft Backup Controller</h2>
120
  <form method="post">
121
+ <label>Set interval (minutes):</label>
122
  <input type="number" name="interval" value="{{ interval }}" min="1">
123
  <button type="submit">Set Timer</button>
124
  </form>
 
128
  </form>
129
  <div class="box">
130
  <p><strong>Last Backup:</strong> {{ last_run }}</p>
131
+ <p><strong>Status Log:</strong><br>{{ status|safe }}</p>
132
  </div>
133
  </body>
134
  </html>
135
+ '''
136
 
137
  @app.route("/", methods=["GET", "POST"])
138
  def index():
139
  global schedule_interval
140
  status = ""
141
  if request.method == "POST":
142
+ if request.form.get("manual_run"):
143
  status = run_backup()
144
  else:
145
  try:
 
151
 
152
  if __name__ == "__main__":
153
  app.run(host="0.0.0.0", port=7860)
154
+
155
+ # Dockerfile
156
+ # ----------
157
+ # FROM python:3.10
158
+ # WORKDIR /app
159
+ # COPY app.py .
160
+ # RUN pip install flask huggingface_hub gdown
161
+ # CMD ["python", "app.py"]