4141
4242ALL_TLDS = list (set (POPULAR_TLDS + COUNTRY_TLDS + NEW_TLDS ))
4343
44+ TLD_MIN_LENGTH = {
45+ "com" : 2 , "net" : 2 , "org" : 2 , "info" : 2 , "biz" : 3 ,
46+
47+ "io" : 2 , "ai" : 2 , "co" : 3 , "me" : 3 ,
48+
49+ "de" : 2 , "fr" : 2 , "it" : 2 , "es" : 2 , "nl" : 3 ,
50+ "ch" : 3 , "at" : 3 , "be" : 3 , "dk" : 3 , "se" : 3 ,
51+ "no" : 3 , "fi" : 3 , "pl" : 3 , "cz" : 3 , "pt" : 3 ,
52+ "gr" : 3 , "tr" : 3 , "ru" : 3 , "uk" : 3 , "au" : 3 ,
53+ "ca" : 3 , "us" : 3 , "jp" : 3 , "kr" : 3 , "cn" : 3 ,
54+ "in" : 3 , "br" : 3 , "mx" : 3 , "ar" : 3 , "cl" : 3 ,
55+ "pe" : 3 , "za" : 3 , "eg" : 3 , "ma" : 3 , "ng" : 3 ,
56+ "ke" : 3 ,
57+
58+ "app" : 3 , "dev" : 3 , "xyz" : 3 , "tech" : 3 ,
59+ "online" : 3 , "site" : 3 , "website" : 3 , "store" : 3 ,
60+ "shop" : 3 , "cloud" : 3 , "digital" : 3 , "blog" : 3 ,
61+ "news" : 3
62+ }
63+
64+ def get_min_length_for_tld (tld : str ) -> int :
65+ """Obtiene la longitud mínima requerida para un TLD"""
66+ return TLD_MIN_LENGTH .get (tld , 3 )
67+
68+ def is_valid_domain_name (base_name : str , tld : str ) -> bool :
69+ """Valida si un nombre de dominio cumple con las reglas del TLD"""
70+ min_length = get_min_length_for_tld (tld )
71+ if len (base_name ) < min_length :
72+ return False
73+ if not re .match (r'^[a-z0-9]([a-z0-9-]*[a-z0-9])?$' , base_name ):
74+ return False
75+ if base_name .startswith ('-' ) or base_name .endswith ('-' ):
76+ return False
77+ if '--' in base_name :
78+ return False
79+ if len (base_name ) > 63 :
80+ return False
81+ return True
82+
4483def clean_domain_name (domain : str ) -> str :
4584 domain = domain .lower ().strip ()
4685 if domain .startswith ('http://' ) or domain .startswith ('https://' ):
@@ -137,6 +176,17 @@ def socket_check():
137176async def check_domain_availability (domain : str ) -> Dict :
138177 start_time = time .time ()
139178
179+ base_name , tld = extract_domain_parts (domain )
180+
181+ if not is_valid_domain_name (base_name , tld ):
182+ return {
183+ 'domain' : domain ,
184+ 'available' : False ,
185+ 'error' : f'Invalid domain: "{ base_name } " does not meet requirements for .{ tld } (min length: { get_min_length_for_tld (tld )} )' ,
186+ 'valid' : False ,
187+ 'check_time' : "0s"
188+ }
189+
140190 dns_available = await check_domain_dns (domain )
141191 whois_available = await check_domain_whois (domain )
142192
@@ -150,6 +200,7 @@ async def check_domain_availability(domain: str) -> Dict:
150200 'available' : is_available ,
151201 'dns_available' : dns_available ,
152202 'whois_available' : whois_available ,
203+ 'valid' : True ,
153204 'check_time' : f"{ check_time } s"
154205 }
155206
@@ -158,8 +209,11 @@ async def check_multiple_domains(base_name: str, tlds: List[str]) -> List[Dict]:
158209
159210 async def check_with_semaphore (tld : str ):
160211 async with semaphore :
161- domain = f"{ base_name } .{ tld } "
162- return await check_domain_availability (domain )
212+ if is_valid_domain_name (base_name , tld ):
213+ domain = f"{ base_name } .{ tld } "
214+ return await check_domain_availability (domain )
215+ else :
216+ return None
163217
164218 tasks = [check_with_semaphore (tld ) for tld in tlds ]
165219 results = await asyncio .gather (* tasks , return_exceptions = True )
@@ -168,7 +222,7 @@ async def check_with_semaphore(tld: str):
168222 for result in results :
169223 if isinstance (result , dict ):
170224 valid_results .append (result )
171- else :
225+ elif result is not None and not isinstance ( result , Exception ) :
172226 print (f"Error checking domain: { result } " )
173227
174228 return valid_results
@@ -180,22 +234,40 @@ async def run_domain_checks(domain_part: str) -> Dict:
180234 "requested_domain" : None ,
181235 "available_domains" : [],
182236 "unavailable_domains" : [],
237+ "invalid_domains" : [],
183238 "total_checked" : 0 ,
184239 "check_summary" : {}
185240 }
186241
242+ invalid_for_tlds = []
243+ for tld in ALL_TLDS :
244+ if not is_valid_domain_name (base_name , tld ):
245+ min_length = get_min_length_for_tld (tld )
246+ invalid_for_tlds .append ({
247+ 'tld' : tld ,
248+ 'reason' : f'Minimum length: { min_length } chars'
249+ })
250+
251+ if invalid_for_tlds :
252+ results ["invalid_domains" ] = {
253+ 'base_name' : base_name ,
254+ 'length' : len (base_name ),
255+ 'invalid_for' : invalid_for_tlds [:10 ]
256+ }
257+
187258 if existing_tld :
188259 exact_result = await check_domain_availability (f"{ base_name } .{ existing_tld } " )
189260 results ["requested_domain" ] = exact_result
190261
191262 other_tlds = [tld for tld in ALL_TLDS if tld != existing_tld ]
192263 all_results = await check_multiple_domains (base_name , other_tlds )
193- all_results .append (exact_result )
264+ if exact_result .get ('valid' , True ):
265+ all_results .append (exact_result )
194266 else :
195267 all_results = await check_multiple_domains (base_name , ALL_TLDS )
196268
197269 for result in all_results :
198- if result [ 'available' ] :
270+ if result . get ( 'available' ) :
199271 results ["available_domains" ].append (result )
200272 else :
201273 results ["unavailable_domains" ].append (result )
@@ -210,6 +282,7 @@ async def run_domain_checks(domain_part: str) -> Dict:
210282 results ["check_summary" ] = {
211283 "total_available" : len (results ["available_domains" ]),
212284 "total_unavailable" : len (results ["unavailable_domains" ]),
285+ "total_invalid" : len (invalid_for_tlds ),
213286 "popular_available" : len (popular_available ),
214287 "country_available" : len ([r for r in results ["available_domains" ]
215288 if any (r ['domain' ].endswith (f'.{ tld } ' ) for tld in COUNTRY_TLDS )]),
0 commit comments