pyproxytools 0.4.5__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. pyproxytools-0.5.0/MANIFEST.in +2 -0
  2. {pyproxytools-0.4.5/pyproxytools.egg-info → pyproxytools-0.5.0}/PKG-INFO +14 -7
  3. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/README.md +6 -1
  4. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproject.toml +22 -0
  5. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/__init__.py +1 -1
  6. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/handlers/http.py +8 -27
  7. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/handlers/https.py +6 -19
  8. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/modules/filter.py +6 -17
  9. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/monitoring/__init__.py +21 -2
  10. pyproxytools-0.5.0/pyproxy/monitoring/messages.pot +235 -0
  11. pyproxytools-0.5.0/pyproxy/monitoring/routes.py +253 -0
  12. pyproxytools-0.5.0/pyproxy/monitoring/translations/en/LC_MESSAGES/messages.mo +0 -0
  13. pyproxytools-0.5.0/pyproxy/monitoring/translations/en/LC_MESSAGES/messages.po +248 -0
  14. pyproxytools-0.5.0/pyproxy/monitoring/translations/fr/LC_MESSAGES/messages.mo +0 -0
  15. pyproxytools-0.5.0/pyproxy/monitoring/translations/fr/LC_MESSAGES/messages.po +248 -0
  16. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/pyproxy.py +9 -23
  17. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/server.py +7 -25
  18. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/utils/args.py +10 -30
  19. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/utils/crypto.py +1 -3
  20. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/utils/logger.py +1 -3
  21. {pyproxytools-0.4.5 → pyproxytools-0.5.0/pyproxytools.egg-info}/PKG-INFO +14 -7
  22. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxytools.egg-info/SOURCES.txt +6 -4
  23. pyproxytools-0.5.0/pyproxytools.egg-info/requires.txt +8 -0
  24. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxytools.egg-info/top_level.txt +0 -1
  25. pyproxytools-0.5.0/requirements.txt +8 -0
  26. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/setup.py +3 -1
  27. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/modules/test_filter.py +2 -6
  28. pyproxytools-0.4.5/benchmark/benchmark.py +0 -165
  29. pyproxytools-0.4.5/benchmark/utils/html.py +0 -179
  30. pyproxytools-0.4.5/benchmark/utils/req.py +0 -43
  31. pyproxytools-0.4.5/pyproxy/monitoring/routes.py +0 -78
  32. pyproxytools-0.4.5/pyproxytools.egg-info/requires.txt +0 -7
  33. pyproxytools-0.4.5/requirements.txt +0 -7
  34. pyproxytools-0.4.5/tests/utils/__init__.py +0 -0
  35. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/LICENSE +0 -0
  36. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/__main__.py +0 -0
  37. {pyproxytools-0.4.5/benchmark/utils → pyproxytools-0.5.0/pyproxy/handlers}/__init__.py +0 -0
  38. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/handlers/client.py +0 -0
  39. {pyproxytools-0.4.5/pyproxy/handlers → pyproxytools-0.5.0/pyproxy/modules}/__init__.py +0 -0
  40. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/modules/cancel_inspect.py +0 -0
  41. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/modules/custom_header.py +0 -0
  42. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/modules/shortcuts.py +0 -0
  43. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/monitoring/auth.py +0 -0
  44. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/monitoring/monitor.py +0 -0
  45. {pyproxytools-0.4.5/pyproxy/modules → pyproxytools-0.5.0/pyproxy/utils}/__init__.py +0 -0
  46. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/utils/config.py +0 -0
  47. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxy/utils/http_req.py +0 -0
  48. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxytools.egg-info/dependency_links.txt +0 -0
  49. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/pyproxytools.egg-info/entry_points.txt +0 -0
  50. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/setup.cfg +0 -0
  51. {pyproxytools-0.4.5/pyproxy/utils → pyproxytools-0.5.0/tests/modules}/__init__.py +0 -0
  52. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/modules/test_cancel_inspect.py +0 -0
  53. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/modules/test_custom_header.py +0 -0
  54. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/modules/test_shortcuts.py +0 -0
  55. {pyproxytools-0.4.5/tests/modules → pyproxytools-0.5.0/tests/utils}/__init__.py +0 -0
  56. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/utils/test_crypto.py +0 -0
  57. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/utils/test_http_req.py +0 -0
  58. {pyproxytools-0.4.5 → pyproxytools-0.5.0}/tests/utils/test_logger.py +0 -0
@@ -0,0 +1,2 @@
1
+ include pyproxy/monitoring/messages.pot
2
+ recursive-include pyproxy/monitoring/translations *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyproxytools
3
- Version: 0.4.5
3
+ Version: 0.5.0
4
4
  Summary: Lightweight and fast python web proxy
5
5
  Author: pyproxytools
6
6
  License-Expression: MIT
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
18
19
  Classifier: Topic :: Internet
19
20
  Classifier: Topic :: Software Development :: Libraries
20
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -22,12 +23,13 @@ Classifier: Topic :: Utilities
22
23
  Classifier: Typing :: Typed
23
24
  Description-Content-Type: text/markdown
24
25
  License-File: LICENSE
25
- Requires-Dist: rich-argparse>=1.7.0
26
- Requires-Dist: pyOpenSSL>=25.0.0
27
- Requires-Dist: requests>=2.31.0
28
- Requires-Dist: Flask>=3.1.0
26
+ Requires-Dist: rich-argparse>=1.7.1
27
+ Requires-Dist: pyOpenSSL>=25.3.0
28
+ Requires-Dist: requests>=2.32.5
29
+ Requires-Dist: Flask>=3.1.2
29
30
  Requires-Dist: Flask-HTTPAuth>=4.8.0
30
- Requires-Dist: psutil>=5.9.8
31
+ Requires-Dist: Flask-Babel>=4.0.0
32
+ Requires-Dist: psutil>=7.1.0
31
33
  Requires-Dist: colorlog>=6.9.0
32
34
  Dynamic: license-file
33
35
 
@@ -118,7 +120,7 @@ If you encounter any problems, or if you want to use the program in a particular
118
120
 
119
121
  ## 🏎️ **Benchmark**
120
122
 
121
- If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark README](benchmark/README.md) for detailed instructions on how to run the benchmarking tests and generate reports.
123
+ If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark repository](https://github.com/pyproxytools/pyproxy-benchmark) for detailed instructions on how to run the benchmarking tests and generate reports.
122
124
 
123
125
  ## 📄 **License**
124
126
 
@@ -138,4 +140,9 @@ If you want to deploy **pyproxy** automatically to remote servers (via source or
138
140
 
139
141
  👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
140
142
 
143
+ ## 🧩 **Python SDK for Administration and Monitoring**
144
+
145
+ A dedicated Python SDK is available to interact programmatically with the **pyproxy** administration and monitoring interface: [**pyproxy-sdk-py**](https://github.com/pyproxytools/pyproxy-sdk-py).
146
+ This SDK provides a simple and consistent API to manage your proxy configuration remotely — allowing you to add or delete domains, manage URLs, create and remove clients, and perform other administrative tasks. It is designed to integrate easily into automation scripts, dashboards, or backend systems that need to control and monitor pyproxy instances.
147
+
141
148
  ---
@@ -85,7 +85,7 @@ If you encounter any problems, or if you want to use the program in a particular
85
85
 
86
86
  ## 🏎️ **Benchmark**
87
87
 
88
- If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark README](benchmark/README.md) for detailed instructions on how to run the benchmarking tests and generate reports.
88
+ If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark repository](https://github.com/pyproxytools/pyproxy-benchmark) for detailed instructions on how to run the benchmarking tests and generate reports.
89
89
 
90
90
  ## 📄 **License**
91
91
 
@@ -105,4 +105,9 @@ If you want to deploy **pyproxy** automatically to remote servers (via source or
105
105
 
106
106
  👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
107
107
 
108
+ ## 🧩 **Python SDK for Administration and Monitoring**
109
+
110
+ A dedicated Python SDK is available to interact programmatically with the **pyproxy** administration and monitoring interface: [**pyproxy-sdk-py**](https://github.com/pyproxytools/pyproxy-sdk-py).
111
+ This SDK provides a simple and consistent API to manage your proxy configuration remotely — allowing you to add or delete domains, manage URLs, create and remove clients, and perform other administrative tasks. It is designed to integrate easily into automation scripts, dashboards, or backend systems that need to control and monitor pyproxy instances.
112
+
108
113
  ---
@@ -17,6 +17,7 @@ classifiers = [
17
17
  "Programming Language :: Python :: 3.10",
18
18
  "Programming Language :: Python :: 3.11",
19
19
  "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
20
21
  "Topic :: Internet",
21
22
  "Topic :: Software Development :: Libraries",
22
23
  "Topic :: Software Development :: Libraries :: Python Modules",
@@ -35,6 +36,27 @@ find = {}
35
36
  [tool.setuptools.dynamic]
36
37
  dependencies = { file = "requirements.txt" }
37
38
 
39
+ [tool.ruff]
40
+ line-length = 100
41
+ src = ["pyproxy", "tests"]
42
+ exclude = [
43
+ ".git",
44
+ "__pycache__",
45
+ "build",
46
+ "dist",
47
+ "venv",
48
+ "setup.py",
49
+ ]
50
+
51
+ [tool.ruff.lint]
52
+ select = ["E", "F", "W", "S"]
53
+
54
+ [tool.ruff.format]
55
+ quote-style = "double"
56
+ indent-style = "space"
57
+ line-ending = "auto"
58
+ skip-magic-trailing-comma = false
59
+
38
60
  [project.scripts]
39
61
  pyproxy = "pyproxy.pyproxy:main"
40
62
 
@@ -5,7 +5,7 @@ that holds the current version number of the application.
5
5
 
6
6
  import os
7
7
 
8
- __version__ = "0.4.5"
8
+ __version__ = "0.5.0"
9
9
 
10
10
  if os.path.isdir("pyproxy/monitoring"):
11
11
  __slim__ = False
@@ -62,9 +62,7 @@ class HttpHandler:
62
62
  new_headers = self.custom_header_result_queue.get(timeout=5)
63
63
  headers.update(new_headers)
64
64
  except Exception:
65
- self.console_logger.warning(
66
- "Timeout while getting custom headers for %s", url
67
- )
65
+ self.console_logger.warning("Timeout while getting custom headers for %s", url)
68
66
  return headers
69
67
 
70
68
  def _rebuild_http_request(self, request_line, headers, body=""):
@@ -86,9 +84,7 @@ class HttpHandler:
86
84
  try:
87
85
  return self.shortcuts_result_queue.get(timeout=5)
88
86
  except Exception:
89
- self.console_logger.warning(
90
- "Timeout while getting shortcut for %s", url
91
- )
87
+ self.console_logger.warning("Timeout while getting shortcut for %s", url)
92
88
  return None
93
89
 
94
90
  def _is_blocked(self, url: str) -> bool:
@@ -150,10 +146,7 @@ class HttpHandler:
150
146
  shortcut_url = self._apply_shortcut(url)
151
147
  if shortcut_url:
152
148
  response = (
153
- f"HTTP/1.1 302 Found\r\n"
154
- f"Location: {shortcut_url}\r\n"
155
- f"Content-Length: 0\r\n"
156
- "\r\n"
149
+ f"HTTP/1.1 302 Found\r\nLocation: {shortcut_url}\r\nContent-Length: 0\r\n\r\n"
157
150
  )
158
151
 
159
152
  client_socket.sendall(response.encode())
@@ -170,16 +163,10 @@ class HttpHandler:
170
163
  request_lines = request_text.split("\r\n")
171
164
  headers = self._get_modified_headers(url, request_text)
172
165
  request_line = request_lines[0]
173
- body = (
174
- request_text.split("\r\n\r\n", 1)[1]
175
- if "\r\n\r\n" in request_text
176
- else ""
177
- )
166
+ body = request_text.split("\r\n\r\n", 1)[1] if "\r\n\r\n" in request_text else ""
178
167
  modified_request = self._rebuild_http_request(request_line, headers, body)
179
168
 
180
- self.forward_request_to_server(
181
- client_socket, modified_request, url, first_line
182
- )
169
+ self.forward_request_to_server(client_socket, modified_request, url, first_line)
183
170
 
184
171
  else:
185
172
  self.forward_request_to_server(client_socket, request, url, first_line)
@@ -199,9 +186,7 @@ class HttpHandler:
199
186
  else:
200
187
  parsed_url = urlparse(url)
201
188
  server_host = parsed_url.hostname
202
- server_port = parsed_url.port or (
203
- 443 if parsed_url.scheme == "https" else 80
204
- )
189
+ server_port = parsed_url.port or (443 if parsed_url.scheme == "https" else 80)
205
190
 
206
191
  try:
207
192
  ip_address = socket.gethostbyname(server_host)
@@ -233,17 +218,13 @@ class HttpHandler:
233
218
  response = server_socket.recv(4096)
234
219
  if response:
235
220
  client_socket.send(response)
236
- self.active_connections[thread_id]["bytes_received"] += len(
237
- response
238
- )
221
+ self.active_connections[thread_id]["bytes_received"] += len(response)
239
222
  else:
240
223
  break
241
224
  except socket.timeout:
242
225
  break
243
226
  except (socket.timeout, socket.gaierror, ConnectionRefusedError, OSError) as e:
244
- self.console_logger.error(
245
- "Error connecting to the server %s : %s", server_host, e
246
- )
227
+ self.console_logger.error("Error connecting to the server %s : %s", server_host, e)
247
228
  response = (
248
229
  f"HTTP/1.1 502 Bad Gateway\r\n"
249
230
  f"Content-Length: {len('Bad Gateway')} \r\n"
@@ -271,12 +271,8 @@ class HttpsHandler:
271
271
 
272
272
  tls_version = ssl_client_socket.version() or "unknown"
273
273
 
274
- server_socket = self._establish_server_connection(
275
- server_host, server_port
276
- )
277
- ssl_server_socket = self._wrap_server_socket_with_ssl(
278
- server_socket, server_host
279
- )
274
+ server_socket = self._establish_server_connection(server_host, server_port)
275
+ ssl_server_socket = self._wrap_server_socket_with_ssl(server_socket, server_host)
280
276
 
281
277
  first_request, full_url, is_blocked = self._process_first_ssl_request(
282
278
  ssl_client_socket, server_host, first_line
@@ -324,9 +320,7 @@ class HttpsHandler:
324
320
 
325
321
  else:
326
322
  try:
327
- server_socket = self._establish_server_connection(
328
- server_host, server_port
329
- )
323
+ server_socket = self._establish_server_connection(server_host, server_port)
330
324
  client_socket.sendall(b"HTTP/1.1 200 Connection Established\r\n\r\n")
331
325
 
332
326
  client_ip = client_socket.getpeername()[0]
@@ -355,9 +349,7 @@ class HttpsHandler:
355
349
  ConnectionRefusedError,
356
350
  OSError,
357
351
  ) as e:
358
- self.console_logger.error(
359
- "Error connecting to the server %s: %s", server_host, e
360
- )
352
+ self.console_logger.error("Error connecting to the server %s: %s", server_host, e)
361
353
  response = (
362
354
  f"HTTP/1.1 502 Bad Gateway\r\n"
363
355
  f"Content-Length: {len('Bad Gateway')} \r\n"
@@ -401,9 +393,7 @@ class HttpsHandler:
401
393
  client_socket.close()
402
394
  server_socket.close()
403
395
  bytes_sent = self.active_connections[thread_id]["bytes_sent"]
404
- bytes_received = self.active_connections[thread_id][
405
- "bytes_received"
406
- ]
396
+ bytes_received = self.active_connections[thread_id]["bytes_received"]
407
397
  self.active_connections.pop(threading.get_ident(), None)
408
398
  return bytes_sent, bytes_received
409
399
  if sock is client_socket:
@@ -411,11 +401,8 @@ class HttpsHandler:
411
401
  self.active_connections[thread_id]["bytes_sent"] += len(data)
412
402
  else:
413
403
  client_socket.sendall(data)
414
- self.active_connections[thread_id]["bytes_received"] += len(
415
- data
416
- )
404
+ self.active_connections[thread_id]["bytes_received"] += len(data)
417
405
  except (socket.error, OSError):
418
- self.logger_config.console_logger("error")
419
406
  client_socket.close()
420
407
  server_socket.close()
421
408
  self.active_connections.pop(threading.get_ident(), None)
@@ -18,9 +18,7 @@ from urllib.parse import urlparse
18
18
  import requests
19
19
 
20
20
 
21
- def load_blacklist(
22
- blocked_sites_path: str, blocked_url_path: str, filter_mode: str
23
- ) -> set:
21
+ def load_blacklist(blocked_sites_path: str, blocked_url_path: str, filter_mode: str) -> set:
24
22
  """
25
23
  Loads blocked FQDNs or URLs from a file or URL into a set for fast lookup.
26
24
 
@@ -50,9 +48,7 @@ def load_blacklist(
50
48
  for line in response.text.splitlines():
51
49
  data.add(line.strip())
52
50
  except requests.exceptions.RequestException as e:
53
- raise requests.exceptions.RequestException(
54
- f"Failed to load data from {url}: {e}"
55
- )
51
+ raise requests.exceptions.RequestException(f"Failed to load data from {url}: {e}")
56
52
  return data
57
53
 
58
54
  if filter_mode == "local":
@@ -88,12 +84,8 @@ def filter_process(
88
84
  manager = multiprocessing.Manager()
89
85
  blocked_data = manager.dict(
90
86
  {
91
- "sites": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[
92
- 0
93
- ],
94
- "urls": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[
95
- 1
96
- ],
87
+ "sites": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[0],
88
+ "urls": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[1],
97
89
  }
98
90
  )
99
91
 
@@ -136,13 +128,10 @@ def filter_process(
136
128
  full_url = server_host
137
129
 
138
130
  if "*" in blocked_data["sites"] or any(
139
- server_host.startswith(blocked_host)
140
- for blocked_host in blocked_data["sites"]
131
+ server_host.startswith(blocked_host) for blocked_host in blocked_data["sites"]
141
132
  ):
142
133
  result_queue.put((server_host, "Blocked"))
143
- elif any(
144
- full_url.startswith(blocked_url) for blocked_url in blocked_data["urls"]
145
- ):
134
+ elif any(full_url.startswith(blocked_url) for blocked_url in blocked_data["urls"]):
146
135
  result_queue.put((full_url, "Blocked"))
147
136
  else:
148
137
  result_queue.put((server_host, "Allowed"))
@@ -7,7 +7,8 @@ server using Flask to provide monitoring endpoints.
7
7
  """
8
8
 
9
9
  import logging
10
- from flask import Flask
10
+ from flask import Flask, request
11
+ from flask_babel import Babel
11
12
  from .monitor import ProxyMonitor
12
13
  from .auth import create_basic_auth
13
14
  from .routes import register_routes
@@ -30,9 +31,27 @@ def start_flask_server(proxy_server, flask_port, flask_pass, debug) -> None:
30
31
  auth = create_basic_auth(flask_pass)
31
32
 
32
33
  app = Flask(__name__, static_folder="static")
34
+ app.config["BABEL_DEFAULT_LOCALE"] = "en"
35
+ app.config["BABEL_SUPPORTED_LOCALES"] = ["fr", "en"]
36
+ app.config["BABEL_DEFAULT_TIMEZONE"] = "Europe/London"
37
+
38
+ def select_locale():
39
+ lang = request.args.get("lang")
40
+ if lang in app.config["BABEL_SUPPORTED_LOCALES"]:
41
+ return lang
42
+ return request.accept_languages.best_match(app.config["BABEL_SUPPORTED_LOCALES"])
43
+
44
+ Babel(app, locale_selector=select_locale)
45
+
46
+ @app.context_processor
47
+ def inject_globals():
48
+ from flask_babel import get_locale
49
+
50
+ return {"get_locale": get_locale}
51
+
33
52
  if not debug:
34
53
  log = logging.getLogger("werkzeug")
35
54
  log.setLevel(logging.ERROR)
36
55
 
37
56
  register_routes(app, auth, proxy_server, ProxyMonitor)
38
- app.run(host="0.0.0.0", port=flask_port) # nosec
57
+ app.run(host="0.0.0.0", port=flask_port) # noqa: S104
@@ -0,0 +1,235 @@
1
+ # Translations template for PROJECT.
2
+ # Copyright (C) 2025 ORGANIZATION
3
+ # This file is distributed under the same license as the PROJECT project.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PROJECT VERSION\n"
10
+ "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11
+ "POT-Creation-Date: 2025-10-12 16:04+0200\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=utf-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Generated-By: Babel 2.17.0\n"
19
+
20
+ #: routes.py:34 templates/index.html:19
21
+ msgid "Next refresh in:"
22
+ msgstr ""
23
+
24
+ #: routes.py:35 templates/index.html:31 templates/index.html:36
25
+ msgid "Loading..."
26
+ msgstr ""
27
+
28
+ #: routes.py:36
29
+ msgid "Main Process"
30
+ msgstr ""
31
+
32
+ #: routes.py:37
33
+ msgid "Subprocesses"
34
+ msgstr ""
35
+
36
+ #: routes.py:38 templates/index.html:23
37
+ msgid "Status"
38
+ msgstr ""
39
+
40
+ #: routes.py:39
41
+ msgid "Configuration"
42
+ msgstr ""
43
+
44
+ #: routes.py:40 templates/index.html:41
45
+ msgid "Active Connections"
46
+ msgstr ""
47
+
48
+ #: routes.py:41 templates/index.html:42
49
+ msgid "Search client or target..."
50
+ msgstr ""
51
+
52
+ #: routes.py:42
53
+ msgid "Blocked sites"
54
+ msgstr ""
55
+
56
+ #: routes.py:43
57
+ msgid "Blocked URLs"
58
+ msgstr ""
59
+
60
+ #: routes.py:44 templates/index.html:62
61
+ msgid "Add"
62
+ msgstr ""
63
+
64
+ #: routes.py:45 templates/index.html:51
65
+ msgid "Add a domain or URL to block"
66
+ msgstr ""
67
+
68
+ #: routes.py:46 templates/index.html:55
69
+ msgid "Domain"
70
+ msgstr ""
71
+
72
+ #: routes.py:47 templates/index.html:56
73
+ msgid "URL"
74
+ msgstr ""
75
+
76
+ #: routes.py:48 templates/index.html:59
77
+ msgid "Value :"
78
+ msgstr ""
79
+
80
+ #: routes.py:49 templates/index.html:26 templates/index.html:49
81
+ msgid "Filtering"
82
+ msgstr ""
83
+
84
+ #: routes.py:50
85
+ msgid "No active connections."
86
+ msgstr ""
87
+
88
+ #: routes.py:51
89
+ msgid "No blocked sites."
90
+ msgstr ""
91
+
92
+ #: routes.py:52
93
+ msgid "No URLs blocked."
94
+ msgstr ""
95
+
96
+ #: routes.py:53
97
+ msgid "Error while deleting :"
98
+ msgstr ""
99
+
100
+ #: routes.py:54
101
+ msgid "Error adding :"
102
+ msgstr ""
103
+
104
+ #: routes.py:55
105
+ msgid "Please enter a value to block."
106
+ msgstr ""
107
+
108
+ #: routes.py:56 routes.py:84
109
+ msgid "Network error"
110
+ msgstr ""
111
+
112
+ #: routes.py:57
113
+ msgid "Error loading data:"
114
+ msgstr ""
115
+
116
+ #: routes.py:58
117
+ msgid "Name:"
118
+ msgstr ""
119
+
120
+ #: routes.py:59
121
+ msgid "PID:"
122
+ msgstr ""
123
+
124
+ #: routes.py:60
125
+ msgid "Status:"
126
+ msgstr ""
127
+
128
+ #: routes.py:61
129
+ msgid "Start Time:"
130
+ msgstr ""
131
+
132
+ #: routes.py:62
133
+ msgid "Client"
134
+ msgstr ""
135
+
136
+ #: routes.py:63
137
+ msgid "Target"
138
+ msgstr ""
139
+
140
+ #: routes.py:64
141
+ msgid "Sent"
142
+ msgstr ""
143
+
144
+ #: routes.py:65
145
+ msgid "Received"
146
+ msgstr ""
147
+
148
+ #: routes.py:66
149
+ msgid "bytes"
150
+ msgstr ""
151
+
152
+ #: routes.py:67
153
+ msgid "Port:"
154
+ msgstr ""
155
+
156
+ #: routes.py:68
157
+ msgid "Flask Port:"
158
+ msgstr ""
159
+
160
+ #: routes.py:69
161
+ msgid "HTML 403:"
162
+ msgstr ""
163
+
164
+ #: routes.py:70
165
+ msgid "Filter Configuration"
166
+ msgstr ""
167
+
168
+ #: routes.py:71
169
+ msgid "Blocked Sites File:"
170
+ msgstr ""
171
+
172
+ #: routes.py:72
173
+ msgid "Blocked URL File:"
174
+ msgstr ""
175
+
176
+ #: routes.py:73
177
+ msgid "Filter Mode:"
178
+ msgstr ""
179
+
180
+ #: routes.py:74
181
+ msgid "Logger Configuration"
182
+ msgstr ""
183
+
184
+ #: routes.py:75
185
+ msgid "Access Log:"
186
+ msgstr ""
187
+
188
+ #: routes.py:76
189
+ msgid "Block Log:"
190
+ msgstr ""
191
+
192
+ #: routes.py:77
193
+ msgid "SSL Inspection"
194
+ msgstr ""
195
+
196
+ #: routes.py:78
197
+ msgid "Inspect CA Cert:"
198
+ msgstr ""
199
+
200
+ #: routes.py:79
201
+ msgid "Inspect CA Key:"
202
+ msgstr ""
203
+
204
+ #: routes.py:80
205
+ msgid "Inspect certs folder:"
206
+ msgstr ""
207
+
208
+ #: routes.py:81
209
+ msgid "Cancel inspect:"
210
+ msgstr ""
211
+
212
+ #: routes.py:82
213
+ msgid "Action"
214
+ msgstr ""
215
+
216
+ #: routes.py:83
217
+ msgid "Unblock"
218
+ msgstr ""
219
+
220
+ #: templates/index.html:24
221
+ msgid "Settings"
222
+ msgstr ""
223
+
224
+ #: templates/index.html:25
225
+ msgid "Connections"
226
+ msgstr ""
227
+
228
+ #: templates/index.html:60
229
+ msgid "e.g.: example.com or http://example.com/page"
230
+ msgstr ""
231
+
232
+ #: templates/index.html:65
233
+ msgid "Search domain or URLs..."
234
+ msgstr ""
235
+