4141
4242ALL_TLDS = list (set (POPULAR_TLDS + COUNTRY_TLDS + NEW_TLDS ))
4343
44+ TLD_MIN_LENGTH = {
45+ "com" : 3 , "net" : 3 , "org" : 3 , "info" : 3 , "biz" : 3 ,
46+ "io" : 3 , "ai" : 3 , "co" : 3 , "me" : 3 ,
47+ "de" : 3 , "fr" : 3 , "it" : 3 , "es" : 3 , "nl" : 3 ,
48+ "ch" : 3 , "at" : 3 , "be" : 3 , "dk" : 3 , "se" : 3 ,
49+ "no" : 3 , "fi" : 3 , "pl" : 3 , "cz" : 3 , "pt" : 3 ,
50+ "gr" : 3 , "tr" : 3 , "ru" : 3 , "uk" : 3 , "au" : 3 ,
51+ "ca" : 3 , "us" : 3 , "jp" : 3 , "kr" : 3 , "cn" : 3 ,
52+ "in" : 3 , "br" : 3 , "mx" : 3 , "ar" : 3 , "cl" : 3 ,
53+ "pe" : 3 , "za" : 3 , "eg" : 3 , "ma" : 3 , "ng" : 3 ,
54+ "ke" : 3 ,
55+
56+ "app" : 3 , "dev" : 3 , "xyz" : 3 , "tech" : 3 ,
57+ "online" : 3 , "site" : 3 , "website" : 3 , "store" : 3 ,
58+ "shop" : 3 , "cloud" : 3 , "digital" : 3 , "blog" : 3 ,
59+ "news" : 3
60+ }
61+
62+ def get_min_length_for_tld (tld : str ) -> int :
63+ """Obtiene la longitud mínima requerida para un TLD"""
64+ return TLD_MIN_LENGTH .get (tld , 3 )
65+
66+ def is_valid_domain_name (base_name : str , tld : str ) -> bool :
67+ """Valida si un nombre de dominio cumple con las reglas del TLD"""
68+ min_length = get_min_length_for_tld (tld )
69+ if len (base_name ) < min_length :
70+ return False
71+ if not re .match (r'^[a-z0-9]([a-z0-9-]*[a-z0-9])?$' , base_name ):
72+ return False
73+ if base_name .startswith ('-' ) or base_name .endswith ('-' ):
74+ return False
75+ if '--' in base_name :
76+ return False
77+ if len (base_name ) > 63 :
78+ return False
79+ return True
80+
4481def clean_domain_name (domain : str ) -> str :
4582 domain = domain .lower ().strip ()
4683 if domain .startswith ('http://' ) or domain .startswith ('https://' ):
@@ -136,6 +173,15 @@ def socket_check():
136173
137174async def check_domain_availability (domain : str ) -> Dict :
138175 start_time = time .time ()
176+ base_name , tld = extract_domain_parts (domain )
177+ if not is_valid_domain_name (base_name , tld ):
178+ return {
179+ 'domain' : domain ,
180+ 'available' : False ,
181+ 'error' : f'Invalid domain: "{ base_name } " does not meet requirements for .{ tld } (min length: { get_min_length_for_tld (tld )} )' ,
182+ 'valid' : False ,
183+ 'check_time' : "0s"
184+ }
139185
140186 dns_available = await check_domain_dns (domain )
141187 whois_available = await check_domain_whois (domain )
@@ -150,6 +196,7 @@ async def check_domain_availability(domain: str) -> Dict:
150196 'available' : is_available ,
151197 'dns_available' : dns_available ,
152198 'whois_available' : whois_available ,
199+ 'valid' : True ,
153200 'check_time' : f"{ check_time } s"
154201 }
155202
@@ -158,8 +205,11 @@ async def check_multiple_domains(base_name: str, tlds: List[str]) -> List[Dict]:
158205
159206 async def check_with_semaphore (tld : str ):
160207 async with semaphore :
161- domain = f"{ base_name } .{ tld } "
162- return await check_domain_availability (domain )
208+ if is_valid_domain_name (base_name , tld ):
209+ domain = f"{ base_name } .{ tld } "
210+ return await check_domain_availability (domain )
211+ else :
212+ return None
163213
164214 tasks = [check_with_semaphore (tld ) for tld in tlds ]
165215 results = await asyncio .gather (* tasks , return_exceptions = True )
@@ -168,7 +218,7 @@ async def check_with_semaphore(tld: str):
168218 for result in results :
169219 if isinstance (result , dict ):
170220 valid_results .append (result )
171- else :
221+ elif result is not None and not isinstance ( result , Exception ) :
172222 print (f"Error checking domain: { result } " )
173223
174224 return valid_results
@@ -180,22 +230,40 @@ async def run_domain_checks(domain_part: str) -> Dict:
180230 "requested_domain" : None ,
181231 "available_domains" : [],
182232 "unavailable_domains" : [],
233+ "invalid_domains" : [],
183234 "total_checked" : 0 ,
184235 "check_summary" : {}
185236 }
186237
238+ invalid_for_tlds = []
239+ for tld in ALL_TLDS :
240+ if not is_valid_domain_name (base_name , tld ):
241+ min_length = get_min_length_for_tld (tld )
242+ invalid_for_tlds .append ({
243+ 'tld' : tld ,
244+ 'reason' : f'Minimum length: { min_length } chars'
245+ })
246+
247+ if invalid_for_tlds :
248+ results ["invalid_domains" ] = {
249+ 'base_name' : base_name ,
250+ 'length' : len (base_name ),
251+ 'invalid_for' : invalid_for_tlds [:10 ]
252+ }
253+
187254 if existing_tld :
188255 exact_result = await check_domain_availability (f"{ base_name } .{ existing_tld } " )
189256 results ["requested_domain" ] = exact_result
190257
191258 other_tlds = [tld for tld in ALL_TLDS if tld != existing_tld ]
192259 all_results = await check_multiple_domains (base_name , other_tlds )
193- all_results .append (exact_result )
260+ if exact_result .get ('valid' , True ):
261+ all_results .append (exact_result )
194262 else :
195263 all_results = await check_multiple_domains (base_name , ALL_TLDS )
196264
197265 for result in all_results :
198- if result [ 'available' ] :
266+ if result . get ( 'available' ) :
199267 results ["available_domains" ].append (result )
200268 else :
201269 results ["unavailable_domains" ].append (result )
@@ -210,6 +278,7 @@ async def run_domain_checks(domain_part: str) -> Dict:
210278 results ["check_summary" ] = {
211279 "total_available" : len (results ["available_domains" ]),
212280 "total_unavailable" : len (results ["unavailable_domains" ]),
281+ "total_invalid" : len (invalid_for_tlds ),
213282 "popular_available" : len (popular_available ),
214283 "country_available" : len ([r for r in results ["available_domains" ]
215284 if any (r ['domain' ].endswith (f'.{ tld } ' ) for tld in COUNTRY_TLDS )]),
0 commit comments