nord-config-generator 1.0.2__tar.gz → 1.0.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nord-config-generator
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: A command-line tool for generating optimized NordVPN WireGuard configurations.
5
5
  Author-email: Ahmed Touhami <mustafachyi272@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/mustafachyi/NordVPN-WireGuard-Config-Generator
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nord-config-generator"
7
- version = "1.0.2"
7
+ version = "1.0.3"
8
8
  authors = [
9
9
  { name="Ahmed Touhami", email="mustafachyi272@gmail.com" },
10
10
  ]
@@ -46,7 +46,6 @@ class GenerationStats:
46
46
  class NordVpnApiClient:
47
47
  NORD_API_BASE_URL = "https://api.nordvpn.com/v1"
48
48
  LOCATION_API_URL = "https://ipinfo.io/json"
49
- COUNTRIES_API_URL = f"{NORD_API_BASE_URL}/servers/countries"
50
49
 
51
50
  def __init__(self, console_manager: ConsoleManager):
52
51
  self._console = console_manager
@@ -75,10 +74,6 @@ class NordVpnApiClient:
75
74
  data = await self._get(url, params=params)
76
75
  return data if isinstance(data, list) else []
77
76
 
78
- async def get_countries(self) -> List[Dict[str, Any]]:
79
- data = await self._get(self.COUNTRIES_API_URL)
80
- return data if isinstance(data, list) else []
81
-
82
77
  async def get_user_geolocation(self) -> Optional[Tuple[float, float]]:
83
78
  data = await self._get(self.LOCATION_API_URL)
84
79
  if not isinstance(data, dict):
@@ -114,12 +109,11 @@ class ConfigurationOrchestrator:
114
109
  self.stats = GenerationStats()
115
110
 
116
111
  async def generate(self) -> Optional[Path]:
117
- user_location, all_servers_data, countries_data = await self._fetch_remote_data()
118
- if not user_location or not all_servers_data or not countries_data:
112
+ user_location, all_servers_data = await self._fetch_remote_data()
113
+ if not user_location or not all_servers_data:
119
114
  return None
120
115
 
121
- country_code_map = {country['name']: country['code'].lower() for country in countries_data}
122
- processed_servers = await self._process_server_data(all_servers_data, user_location, country_code_map)
116
+ processed_servers = await self._process_server_data(all_servers_data, user_location)
123
117
 
124
118
  sorted_servers = sorted(processed_servers, key=lambda s: (s.load, s.distance))
125
119
  best_servers_by_location = self._get_best_servers(sorted_servers)
@@ -130,20 +124,19 @@ class ConfigurationOrchestrator:
130
124
  await self._save_all_configurations(sorted_servers, best_servers_by_location, servers_info)
131
125
  return self._output_dir
132
126
 
133
- async def _fetch_remote_data(self) -> Tuple[Optional[Tuple[float, float]], List[Dict[str, Any]], List[Dict[str, Any]]]:
127
+ async def _fetch_remote_data(self) -> Tuple[Optional[Tuple[float, float]], List[Dict[str, Any]]]:
134
128
  with self._console.create_progress_bar() as progress:
135
- task = progress.add_task("Fetching remote data...", total=3)
136
- user_location, all_servers_data, countries_data = await asyncio.gather(
129
+ task = progress.add_task("Fetching remote data...", total=2)
130
+ user_location, all_servers_data = await asyncio.gather(
137
131
  self._api_client.get_user_geolocation(),
138
- self._api_client.get_all_servers(),
139
- self._api_client.get_countries()
132
+ self._api_client.get_all_servers()
140
133
  )
141
- progress.update(task, advance=3)
142
- return user_location, all_servers_data, countries_data
134
+ progress.update(task, advance=2)
135
+ return user_location, all_servers_data
143
136
 
144
- async def _process_server_data(self, all_servers_data: List[Dict[str, Any]], user_location: Tuple[float, float], country_code_map: Dict[str, str]) -> List[Server]:
137
+ async def _process_server_data(self, all_servers_data: List[Dict[str, Any]], user_location: Tuple[float, float]) -> List[Server]:
145
138
  loop = asyncio.get_running_loop()
146
- parse_func = partial(self._parse_server_data, user_location=user_location, country_code_map=country_code_map)
139
+ parse_func = partial(self._parse_server_data, user_location=user_location)
147
140
  with ThreadPoolExecutor(max_workers=min(32, (os.cpu_count() or 1) + 4)) as executor:
148
141
  tasks = [loop.run_in_executor(executor, parse_func, s) for s in all_servers_data]
149
142
  processed_servers = await asyncio.gather(*tasks)
@@ -210,14 +203,11 @@ class ConfigurationOrchestrator:
210
203
  return f"[Interface]\nPrivateKey = {private_key}\nAddress = 10.5.0.2/16\nDNS = {preferences.dns}\n\n[Peer]\nPublicKey = {server.public_key}\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = {endpoint}:51820\nPersistentKeepalive = {preferences.persistent_keepalive}"
211
204
 
212
205
  @staticmethod
213
- def _parse_server_data(server_data: Dict[str, Any], user_location: Tuple[float, float], country_code_map: Dict[str, str]) -> Optional[Server]:
206
+ def _parse_server_data(server_data: Dict[str, Any], user_location: Tuple[float, float]) -> Optional[Server]:
214
207
  try:
215
208
  location = server_data['locations'][0]
216
- country_name = location['country']['name']
217
- country_code = country_code_map.get(country_name)
218
- if not country_code:
219
- return None
220
-
209
+ country_info = location['country']
210
+
221
211
  public_key = next(
222
212
  m['value'] for t in server_data['technologies']
223
213
  if t['identifier'] == 'wireguard_udp'
@@ -229,8 +219,8 @@ class ConfigurationOrchestrator:
229
219
  return Server(
230
220
  name=server_data['name'], hostname=server_data['hostname'],
231
221
  station=server_data['station'], load=int(server_data.get('load', 0)),
232
- country=country_name, country_code=country_code,
233
- city=location['country'].get('city', {}).get('name', 'Unknown'),
222
+ country=country_info['name'], country_code=country_info['code'].lower(),
223
+ city=country_info.get('city', {}).get('name', 'Unknown'),
234
224
  latitude=location['latitude'], longitude=location['longitude'],
235
225
  public_key=public_key, distance=distance
236
226
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nord-config-generator
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: A command-line tool for generating optimized NordVPN WireGuard configurations.
5
5
  Author-email: Ahmed Touhami <mustafachyi272@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/mustafachyi/NordVPN-WireGuard-Config-Generator