httpz

- Hyper-fast HTTP Scraping Tool
git clone git://git.acid.vegas/httpz.git
Log | Files | Refs | Archive | README | LICENSE

formatters.py (4465B)

      1 #!/usr/bin/env python3
      2 # HTTPZ Web Scanner - Developed by acidvegas in Python (https://github.com/acidvegas/httpz)
      3 # httpz/formatters.py
      4 
      5 from .colors import Colors
      6 from .utils  import human_size
      7 
      8 def format_console_output(result: dict, debug: bool = False, show_fields: dict = None, match_codes: set = None, exclude_codes: set = None) -> str:
      9     '''
     10     Format the output with colored sections
     11     
     12     :param result: Dictionary containing domain check results
     13     :param debug: Whether to show error states
     14     :param show_fields: Dictionary of fields to show
     15     :param match_codes: Set of status codes to match
     16     :param exclude_codes: Set of status codes to exclude
     17     '''
     18     if result['status'] < 0 and not debug:
     19         return ''
     20         
     21     if match_codes and result['status'] not in match_codes:
     22         return ''
     23     if exclude_codes and result['status'] in exclude_codes:
     24         return ''
     25 
     26     parts = []
     27     
     28     # Status code
     29     if show_fields.get('status_code'):
     30         if result['status'] < 0:
     31             status = f"{Colors.RED}[{result['status']}]{Colors.RESET}"
     32         elif 200 <= result['status'] < 300:
     33             status = f"{Colors.GREEN}[{result['status']}]{Colors.RESET}"
     34         elif 300 <= result['status'] < 400:
     35             status = f"{Colors.YELLOW}[{result['status']}]{Colors.RESET}"
     36         else:
     37             status = f"{Colors.RED}[{result['status']}]{Colors.RESET}"
     38         parts.append(status)
     39     
     40     # Domain (always shown)
     41     parts.append(f"[{result['url']}]")
     42     
     43     # Title
     44     if show_fields.get('title') and result.get('title'):
     45         parts.append(f"{Colors.DARK_GREEN}[{result['title']}]{Colors.RESET}")
     46     
     47     # Body preview
     48     if show_fields.get('body') and result.get('body'):
     49         body = result['body'][:100] + ('...' if len(result['body']) > 100 else '')
     50         parts.append(f"{Colors.BLUE}[{body}]{Colors.RESET}")
     51     
     52     # IPs
     53     if show_fields.get('ip') and result.get('ips'):
     54         ips_text = ', '.join(result['ips'])
     55         parts.append(f"{Colors.YELLOW}[{ips_text}]{Colors.RESET}")
     56 
     57     # Favicon hash
     58     if show_fields.get('favicon') and result.get('favicon_hash'):
     59         parts.append(f"{Colors.PURPLE}[{result['favicon_hash']}]{Colors.RESET}")
     60 
     61     # Headers
     62     if show_fields.get('headers') and result.get('headers'):
     63         headers_text = [f"{k}: {v}" for k, v in result['headers'].items()]
     64         parts.append(f"{Colors.CYAN}[{', '.join(headers_text)}]{Colors.RESET}")
     65     else:
     66         if show_fields.get('content_type') and result.get('content_type'):
     67             parts.append(f"{Colors.HEADER}[{result['content_type']}]{Colors.RESET}")
     68         
     69         if show_fields.get('content_length') and result.get('content_length'):
     70             try:
     71                 size = human_size(int(result['content_length']))
     72                 parts.append(f"{Colors.PINK}[{size}]{Colors.RESET}")
     73             except (ValueError, TypeError):
     74                 parts.append(f"{Colors.PINK}[{result['content_length']}]{Colors.RESET}")
     75     
     76     # CNAME
     77     if show_fields.get('cname') and result.get('cname'):
     78         parts.append(f"{Colors.PURPLE}[CNAME: {result['cname']}]{Colors.RESET}")
     79     
     80     # Redirect Chain
     81     if show_fields.get('follow_redirects') and result.get('redirect_chain'):
     82         chain = ' -> '.join(result['redirect_chain'])
     83         parts.append(f"{Colors.YELLOW}[Redirects: {chain}]{Colors.RESET}")
     84 
     85     # TLS Certificate Info
     86     if result.get('tls'):
     87         cert = result['tls']
     88         tls_parts = []
     89         if cert.get('common_name'):
     90             tls_parts.append(f"Subject: {cert['common_name']}")
     91         if cert.get('issuer'):
     92             tls_parts.append(f"Issuer: {cert['issuer']}")
     93         if cert.get('fingerprint'):
     94             tls_parts.append(f"Fingerprint: {cert['fingerprint'][:16]}...")
     95         if cert.get('alt_names'):
     96             tls_parts.append(f"SANs: {', '.join(cert['alt_names'][:3])}")
     97         if cert.get('not_before') and cert.get('not_after'):
     98             tls_parts.append(f"Valid: {cert['not_before'].split('T')[0]} to {cert['not_after'].split('T')[0]}")
     99         if cert.get('version'):
    100             tls_parts.append(f"Version: {cert['version']}")
    101         if cert.get('serial_number'):
    102             tls_parts.append(f"Serial: {cert['serial_number'][:16]}...")
    103         
    104         if tls_parts:  # Only add TLS info if we have any parts
    105             parts.append(f"{Colors.GREEN}[{' | '.join(tls_parts)}]{Colors.RESET}")
    106 
    107     return ' '.join(parts)