ChandimaPrabath commited on
Commit
1fa8166
·
1 Parent(s): 10ba288

0.0.2.3 V Beta. added download episode.

Browse files
Files changed (3) hide show
  1. LoadBalancer.py +45 -1
  2. api.py +23 -0
  3. app.py +6 -16
LoadBalancer.py CHANGED
@@ -19,7 +19,7 @@ download_progress = {}
19
 
20
  class LoadBalancer:
21
  def __init__(self, cache_dir, index_file, token, repo, polling_interval=10, max_retries=3, initial_delay=1):
22
- self.version = "0.0.2.2 V Beta"
23
  self.instances = []
24
  self.instances_health = {}
25
  self.polling_interval = polling_interval
@@ -264,6 +264,50 @@ class LoadBalancer:
264
  logging.error("No suitable instance found for downloading the film.")
265
  return {"error": "No suitable instance found for downloading the film."}
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  def _convert_to_gb(self, space_str):
268
  """
269
  Converts a space string like '50 GB' or '3.33 GB' to a float representing the number of GB.
 
19
 
20
  class LoadBalancer:
21
  def __init__(self, cache_dir, index_file, token, repo, polling_interval=10, max_retries=3, initial_delay=1):
22
+ self.version = "0.0.2.3 V Beta"
23
  self.instances = []
24
  self.instances_health = {}
25
  self.polling_interval = polling_interval
 
264
  logging.error("No suitable instance found for downloading the film.")
265
  return {"error": "No suitable instance found for downloading the film."}
266
 
267
+ def download_episode_to_best_instance(self, title, season, episode):
268
+ """
269
+ Downloads a episode to the first instance that has more free space on the self.instance_health list variable.
270
+ The instance_health looks like this:
271
+ {
272
+ "https://unicone-studio-instance1.hf.space": {
273
+ "total": "50 GB",
274
+ "used": "3.33 GB"
275
+ }
276
+ }
277
+ Args:
278
+ title (str): The title of the Tv show.
279
+ season (str): The season of the Tv show.
280
+ episode (str): The title of the Tv show.
281
+ """
282
+ best_instance = None
283
+ max_free_space = -1
284
+
285
+ # Calculate free space for each instance
286
+ for instance_url, space_info in self.instances_health.items():
287
+ total_space = self._convert_to_gb(space_info['total'])
288
+ used_space = self._convert_to_gb(space_info['used'])
289
+ free_space = total_space - used_space
290
+
291
+ if free_space > max_free_space:
292
+ max_free_space = free_space
293
+ best_instance = instance_url
294
+
295
+ if best_instance:
296
+ result = self.instances_api.download_episode(best_instance, title, season, episode)
297
+ episode_id = result["episode_id"]
298
+ status = result["status"]
299
+ progress_url = f'{best_instance}/api/progress/{episode_id}'
300
+ response = {
301
+ "film_id":episode_id,
302
+ "status":status,
303
+ "progress_url":progress_url
304
+ }
305
+
306
+ return response
307
+ else:
308
+ logging.error("No suitable instance found for downloading the film.")
309
+ return {"error": "No suitable instance found for downloading the film."}
310
+
311
  def _convert_to_gb(self, space_str):
312
  """
313
  Converts a space string like '50 GB' or '3.33 GB' to a float representing the number of GB.
api.py CHANGED
@@ -38,3 +38,26 @@ class InstancesAPI:
38
  data = {"error": str(e)}
39
 
40
  return data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  data = {"error": str(e)}
39
 
40
  return data
41
+
42
+ def download_episode(self, instance_url, title, season, episode):
43
+ """
44
+ Download a film to an instance.
45
+
46
+ If the download started, it returns a JSON like this:
47
+ example:
48
+ {"film_id": "my_spy_2020",
49
+ "status": "Download started"}
50
+
51
+ If the film has already been downloaded, it will return the video file.
52
+ """
53
+ data = {}
54
+ try:
55
+ response = requests.get(f"{instance_url}/api/tv/{title}/{season}/{episode}")
56
+ response.raise_for_status()
57
+ data = response.json()
58
+
59
+ except requests.exceptions.RequestException as e:
60
+ logging.error(f"Error contacting instance {instance_url}: {e}")
61
+ data = {"error": str(e)}
62
+
63
+ return data
app.py CHANGED
@@ -64,10 +64,8 @@ def get_tv_show_api(title, season, episode):
64
  if title in tv_store_data and season in tv_store_data[title]:
65
  for ep in tv_store_data[title][season]:
66
  if episode in ep:
67
- cache_path = tv_store_data[title][season][ep]
68
- print(cache_path)
69
- if os.path.exists(cache_path):
70
- return send_from_directory(os.path.dirname(cache_path), os.path.basename(cache_path))
71
 
72
  tv_path = load_balancer.find_tv_path(title)
73
 
@@ -89,18 +87,10 @@ def get_tv_show_api(title, season, episode):
89
  if not episode_path:
90
  return jsonify({"error": "Episode not found"}), 404
91
 
92
- cache_path = os.path.join(CACHE_DIR, episode_path)
93
- file_url = f"https://huggingface.co/{REPO}/resolve/main/{episode_path}"
94
- proxies = load_balancer.get_system_proxies()
95
- episode_id = load_balancer.encode_episodeid(title, season, episode)
96
-
97
- # Start the download in a separate thread if not already downloading
98
- if episode_id not in load_balancer.download_threads or not load_balancer.download_threads[episode_id].is_alive():
99
- thread = Thread(target=load_balancer.download_episode, args=(file_url, TOKEN, cache_path, proxies, episode_id, title))
100
- load_balancer.download_threads[episode_id] = thread
101
- thread.start()
102
-
103
- return jsonify({"status": "Download started", "episode_id": episode_id})
104
 
105
  @app.route('/api/progress/<id>', methods=['GET'])
106
  def get_progress_api(id):
 
64
  if title in tv_store_data and season in tv_store_data[title]:
65
  for ep in tv_store_data[title][season]:
66
  if episode in ep:
67
+ url = tv_store_data[title][season][ep]
68
+ return jsonify({"url":url})
 
 
69
 
70
  tv_path = load_balancer.find_tv_path(title)
71
 
 
87
  if not episode_path:
88
  return jsonify({"error": "Episode not found"}), 404
89
 
90
+ # Start the download in a instance
91
+ response = load_balancer.download_episode_to_best_instance(title=title, season=season, episode=episode)
92
+ if response:
93
+ return jsonify(response)
 
 
 
 
 
 
 
 
94
 
95
  @app.route('/api/progress/<id>', methods=['GET'])
96
  def get_progress_api(id):