ChandimaPrabath commited on
Commit
4b81310
·
1 Parent(s): 6d1a377

0.0.1 V Beta

Browse files
Files changed (3) hide show
  1. LoadBalancer.py +73 -0
  2. api.py +17 -0
  3. app.py +48 -7
LoadBalancer.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import logging
3
+ from threading import Thread, Event, Timer
4
+ from api import InstancesAPI
5
+
6
+ class LoadBalancer:
7
+ def __init__(self, polling_interval=60, max_retries=3, initial_delay=1):
8
+ self.version = "0.0.1 V Beta"
9
+ self.instances = []
10
+ self.polling_interval = polling_interval
11
+ self.max_retries = max_retries
12
+ self.initial_delay = initial_delay
13
+ self.stop_event = Event()
14
+ self.instances_api = InstancesAPI(self.instances)
15
+
16
+ def register_instance(self, instance_url):
17
+ if instance_url not in self.instances:
18
+ self.instances.append(instance_url)
19
+ logging.info(f"Registered instance {instance_url}")
20
+ else:
21
+ logging.info(f"Instance {instance_url} is already registered.")
22
+
23
+ def remove_instance(self, instance_url):
24
+ if instance_url in self.instances:
25
+ self.instances.remove(instance_url)
26
+ logging.info(f"Removed instance {instance_url}")
27
+ else:
28
+ logging.info(f"Instance {instance_url} not found for removal.")
29
+
30
+ def get_reports(self):
31
+ reports = self.instances_api.fetch_reports()
32
+ for instance_url in self.instances[:]: # Copy list to avoid modification during iteration
33
+ if instance_url in reports:
34
+ report = reports[instance_url]
35
+ logging.info(f"Report from {instance_url}: {report}")
36
+ self.process_report(instance_url, report)
37
+ else:
38
+ logging.error(f"Failed to get report from {instance_url}. Removing instance.")
39
+ self.remove_instance(instance_url)
40
+
41
+ def process_report(self, instance_url, report):
42
+ # Process the report (film_store, tv_store, cache_size) here
43
+ logging.info(f"Processing report from {instance_url}")
44
+ # Example: Print the film_store and tv_store
45
+ logging.info(f"Film Store: {report.get('film_store')}")
46
+ logging.info(f"TV Store: {report.get('tv_store')}")
47
+ logging.info(f"Cache Size: {report.get('cache_size')}")
48
+
49
+ def start_polling(self):
50
+ logging.info("Starting polling.")
51
+ while not self.stop_event.is_set():
52
+ self.get_reports()
53
+ time.sleep(self.polling_interval)
54
+ logging.info("Polling stopped.")
55
+
56
+ def stop_polling(self):
57
+ logging.info("Stopping polling.")
58
+ self.stop_event.set()
59
+
60
+ if __name__ == "__main__":
61
+ logging.basicConfig(level=logging.INFO)
62
+
63
+ load_balancer = LoadBalancer()
64
+
65
+ # Example registration (in real use, handle this via an API endpoint)
66
+ load_balancer.register_instance("http://localhost:5000")
67
+
68
+ # Start polling in a separate thread
69
+ polling_thread = Thread(target=load_balancer.start_polling)
70
+ polling_thread.start()
71
+
72
+ # Stop polling after some time for demonstration purposes
73
+ Timer(300, load_balancer.stop_polling).start() # Stop after 5 minutes
api.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import logging
3
+
4
+ class InstancesAPI:
5
+ def __init__(self, instances):
6
+ self.instances = instances
7
+
8
+ def fetch_reports(self):
9
+ reports = {}
10
+ for instance_url in self.instances:
11
+ try:
12
+ response = requests.get(f"{instance_url}/api/get/report")
13
+ response.raise_for_status()
14
+ reports[instance_url] = response.json()
15
+ except requests.exceptions.RequestException as e:
16
+ logging.error(f"Error contacting instance {instance_url}: {e}")
17
+ return reports
app.py CHANGED
@@ -8,6 +8,15 @@ from hf_scrapper import download_film, download_episode, get_system_proxies, get
8
  from indexer import indexer
9
  from tvdb import fetch_and_cache_json
10
  import re
 
 
 
 
 
 
 
 
 
11
 
12
  app = Flask(__name__)
13
  CORS(app)
@@ -18,6 +27,7 @@ INDEX_FILE = os.getenv("INDEX_FILE")
18
  TOKEN = os.getenv("TOKEN")
19
  FILM_STORE_JSON_PATH = os.path.join(CACHE_DIR, "film_store.json")
20
  TV_STORE_JSON_PATH = os.path.join(CACHE_DIR, "tv_store.json")
 
21
  REPO = os.getenv("REPO")
22
  download_threads = {}
23
 
@@ -41,7 +51,6 @@ with open(INDEX_FILE, 'r') as f:
41
  file_structure = json.load(f)
42
 
43
  # Function Definitions
44
-
45
  def load_json(file_path):
46
  """Load JSON data from a file."""
47
  with open(file_path, 'r') as file:
@@ -115,6 +124,18 @@ def bytes_to_human_readable(num, suffix="B"):
115
  def encode_episodeid(title,season,episode):
116
  return f"{title}_{season}_{episode}"
117
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  def get_all_tv_shows(indexed_cache):
119
  """Get all TV shows from the indexed cache structure JSON file."""
120
  tv_shows = {}
@@ -283,7 +304,7 @@ def get_tv_store_api():
283
 
284
  @app.route('/api/film/store', methods=['GET'])
285
  def get_film_store_api():
286
- """Endpoint to get the TV store JSON."""
287
  if os.path.exists(FILM_STORE_JSON_PATH):
288
  with open(FILM_STORE_JSON_PATH, 'r') as json_file:
289
  tv_store_data = json.load(json_file)
@@ -362,15 +383,35 @@ def get_all_tvshows_api():
362
 
363
  #############################################################
364
  # unique api's
365
- @app.route('/api/register/<instanceid>',methods=['POST'])
366
- def register_instance(instanceid):
367
- # need to add instance registration logic
368
- return jsonify({f'{instanceid} registered'}), 200
 
 
 
 
 
 
 
 
 
 
 
 
369
 
 
 
 
 
370
  # Routes
371
  @app.route('/')
372
  def index():
373
- return "Load Balancer is Running ..."
 
 
 
 
374
 
375
  # Main entry point
376
  if __name__ == "__main__":
 
8
  from indexer import indexer
9
  from tvdb import fetch_and_cache_json
10
  import re
11
+ import logging
12
+ from LoadBalancer import LoadBalancer
13
+
14
+ logging.basicConfig(level=logging.INFO)
15
+ load_balancer = LoadBalancer()
16
+
17
+ # Start polling in a separate thread
18
+ polling_thread = threading.Thread(target=load_balancer.start_polling)
19
+ polling_thread.start()
20
 
21
  app = Flask(__name__)
22
  CORS(app)
 
27
  TOKEN = os.getenv("TOKEN")
28
  FILM_STORE_JSON_PATH = os.path.join(CACHE_DIR, "film_store.json")
29
  TV_STORE_JSON_PATH = os.path.join(CACHE_DIR, "tv_store.json")
30
+ INSTANCE_REGISTER_JSON_PATH = os.path.join(CACHE_DIR, "instance_register.json")
31
  REPO = os.getenv("REPO")
32
  download_threads = {}
33
 
 
51
  file_structure = json.load(f)
52
 
53
  # Function Definitions
 
54
  def load_json(file_path):
55
  """Load JSON data from a file."""
56
  with open(file_path, 'r') as file:
 
124
  def encode_episodeid(title,season,episode):
125
  return f"{title}_{season}_{episode}"
126
 
127
+ def is_valid_url(url):
128
+ # Simple URL validation (could be more complex if needed)
129
+ regex = re.compile(
130
+ r'^(?:http|ftp)s?://' # http:// or https://
131
+ r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...
132
+ r'localhost|' # localhost...
133
+ r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4
134
+ r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6
135
+ r'(?::\d+)?' # optional port
136
+ r'(?:/?|[/?]\S+)$', re.IGNORECASE)
137
+ return re.match(regex, url) is not None
138
+
139
  def get_all_tv_shows(indexed_cache):
140
  """Get all TV shows from the indexed cache structure JSON file."""
141
  tv_shows = {}
 
304
 
305
  @app.route('/api/film/store', methods=['GET'])
306
  def get_film_store_api():
307
+ """Endpoint to get the film store JSON."""
308
  if os.path.exists(FILM_STORE_JSON_PATH):
309
  with open(FILM_STORE_JSON_PATH, 'r') as json_file:
310
  tv_store_data = json.load(json_file)
 
383
 
384
  #############################################################
385
  # unique api's
386
+ @app.route('/api/register', methods=['POST'])
387
+ def register_instance():
388
+ try:
389
+ data = request.json
390
+ if not data or "url" not in data:
391
+ return jsonify({"error": "No URL provided"}), 400
392
+
393
+ url = data["url"]
394
+ if not is_valid_url(url):
395
+ return jsonify({"error": "Invalid URL"}), 400
396
+
397
+ # Register the instance
398
+ load_balancer.register_instance(url)
399
+ logging.info(f"Instance registered: {url}")
400
+
401
+ return jsonify({"message": f"Instance {url} registered successfully"}), 200
402
 
403
+ except Exception as e:
404
+ logging.error(f"Error registering instance: {e}")
405
+ return jsonify({"error": "Failed to register instance"}), 500
406
+ #############################################################
407
  # Routes
408
  @app.route('/')
409
  def index():
410
+ return f"Load Balancer is Running {load_balancer.version}"
411
+
412
+ @app.route('/instances',method=["GET"])
413
+ def get_instances():
414
+ return load_balancer.instances
415
 
416
  # Main entry point
417
  if __name__ == "__main__":