131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
"""
|
||
WHOIS lookup plugin – outputs a formatted code block with emojis and aligned columns.
|
||
"""
|
||
|
||
import logging
|
||
import whois
|
||
import ipaddress
|
||
import re
|
||
import asyncio
|
||
import simplematrixbotlib as botlib
|
||
from plugins.common import collapsible_summary, html_escape, code_block
|
||
|
||
def is_valid_domain(domain):
|
||
pattern = r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$|^[a-zA-Z0-9-]{1,63}$'
|
||
return re.match(pattern, domain) is not None
|
||
|
||
def is_valid_ip(ip):
|
||
try:
|
||
ipaddress.ip_address(ip)
|
||
return True
|
||
except ValueError:
|
||
return False
|
||
|
||
def _build_rows(data):
|
||
"""Build a list of (emoji, label, value) tuples from WHOIS data."""
|
||
rows = []
|
||
|
||
# Domain
|
||
domain_name = data.domain_name
|
||
if isinstance(domain_name, list):
|
||
domain_name = ', '.join(domain_name)
|
||
rows.append(('🌐', 'Domain', domain_name or 'N/A'))
|
||
|
||
# Registrar / WHOIS Server
|
||
if data.registrar:
|
||
rows.append(('🏢', 'Registrar', data.registrar))
|
||
if data.whois_server:
|
||
rows.append(('📡', 'WHOIS Server', data.whois_server))
|
||
|
||
# Dates
|
||
creation_date = data.creation_date
|
||
if creation_date:
|
||
if isinstance(creation_date, list):
|
||
creation_date = creation_date[0]
|
||
rows.append(('📅', 'Created', str(creation_date)))
|
||
|
||
updated_date = data.updated_date
|
||
if updated_date:
|
||
if isinstance(updated_date, list):
|
||
updated_date = updated_date[0]
|
||
rows.append(('📝', 'Updated', str(updated_date)))
|
||
|
||
expiration_date = data.expiration_date
|
||
if expiration_date:
|
||
if isinstance(expiration_date, list):
|
||
expiration_date = expiration_date[0]
|
||
rows.append(('⏰', 'Expires', str(expiration_date)))
|
||
|
||
# Name servers
|
||
if data.name_servers:
|
||
ns_sorted = sorted(data.name_servers)
|
||
ns_text = ', '.join(ns_sorted[:5])
|
||
if len(ns_sorted) > 5:
|
||
ns_text += f' (+{len(ns_sorted)-5} more)'
|
||
rows.append(('🌍', 'Name Servers', ns_text))
|
||
|
||
# Status
|
||
if data.status:
|
||
status = data.status
|
||
if isinstance(status, list):
|
||
status = ', '.join(status[:3])
|
||
rows.append(('🔒', 'Status', str(status)))
|
||
|
||
# Contact info
|
||
if data.org:
|
||
rows.append(('🏛️', 'Organization', data.org))
|
||
if data.country:
|
||
rows.append(('🌍', 'Country', data.country))
|
||
if data.state:
|
||
rows.append(('🏙️', 'State', data.state))
|
||
if data.city:
|
||
rows.append(('🏡', 'City', data.city))
|
||
|
||
return rows
|
||
|
||
async def handle_command(room, message, bot, prefix, config):
|
||
match = botlib.MessageMatch(room, message, bot, prefix)
|
||
if match.is_not_from_this_bot() and match.prefix() and match.command("whois"):
|
||
args = match.args()
|
||
if len(args) < 1:
|
||
await bot.api.send_text_message(room.room_id, "Usage: !whois <domain/ip>\nExample: !whois example.com")
|
||
return
|
||
|
||
query = args[0].strip()
|
||
if not is_valid_domain(query) and not is_valid_ip(query):
|
||
await bot.api.send_text_message(room.room_id, f"Invalid input: {html_escape(query)}")
|
||
return
|
||
|
||
await bot.api.send_text_message(room.room_id, f"🔍 Performing WHOIS lookup for {html_escape(query)}...")
|
||
|
||
try:
|
||
loop = asyncio.get_running_loop()
|
||
data = await loop.run_in_executor(None, whois.whois, query)
|
||
|
||
rows = _build_rows(data)
|
||
sections = [{"title": "", "rows": rows}] # no section header
|
||
block = code_block(f"🌐 WHOIS Report: {html_escape(query)}", sections)
|
||
output = collapsible_summary(f"🌐 WHOIS Report: {html_escape(query)}", block)
|
||
await bot.api.send_markdown_message(room.room_id, output)
|
||
|
||
except whois.parser.PywhoisError as e:
|
||
await bot.api.send_text_message(room.room_id, f"❌ WHOIS lookup failed: {html_escape(str(e))}")
|
||
except Exception as e:
|
||
await bot.api.send_text_message(room.room_id, f"❌ Unexpected error: {html_escape(str(e))}")
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Plugin Metadata
|
||
# ---------------------------------------------------------------------------
|
||
|
||
__version__ = "1.2.1"
|
||
__author__ = "Funguy Bot"
|
||
__description__ = "Domain WHOIS lookup"
|
||
__help__ = """
|
||
<details>
|
||
<summary><strong>!whois</strong> – WHOIS lookup</summary>
|
||
<pre>
|
||
!whois <domain or IP> Shows registrar, dates, nameservers, etc. in a clean table.
|
||
</pre>
|
||
</details>
|
||
"""
|