This commit is contained in:
2025-09-05 21:44:38 +02:00
commit 316102bbc4
6 changed files with 590 additions and 0 deletions

456
wifi_qr.py Normal file
View File

@@ -0,0 +1,456 @@
#!/usr/bin/env python3
"""
Generatore di QR Code Universale
Supporta WiFi, URL, testo, email, SMS, contatti vCard, eventi calendario e altro
"""
import qrcode
from PIL import Image
import argparse
import sys
import os
import re
from datetime import datetime
from urllib.parse import quote
class UniversalQRGenerator:
def __init__(self):
self.qr_types = {
'wifi': 'Connessione WiFi',
'url': 'URL/Link web',
'text': 'Testo semplice',
'email': 'Email',
'sms': 'SMS',
'phone': 'Numero telefono',
'vcard': 'Biglietto da visita (vCard)',
'event': 'Evento calendario',
'geo': 'Posizione geografica',
'whatsapp': 'Messaggio WhatsApp',
'raw': 'Contenuto personalizzato'
}
# === GENERATORI DI CONTENUTO ===
def generate_wifi_qr(self, ssid, password=None, security='WPA', hidden=False):
"""Genera QR code per WiFi"""
if security not in ['WPA', 'WEP', 'nopass']:
raise ValueError("Sicurezza deve essere: WPA, WEP o nopass")
ssid_escaped = self._escape_wifi_chars(ssid)
password_escaped = self._escape_wifi_chars(password) if password else ""
wifi_string = f"WIFI:T:{security};"
wifi_string += f"S:{ssid_escaped};"
if password and security != 'nopass':
wifi_string += f"P:{password_escaped};"
if hidden:
wifi_string += "H:true;"
wifi_string += ";"
return wifi_string
def generate_url_qr(self, url):
"""Genera QR code per URL"""
if not url.startswith(('http://', 'https://')):
url = 'https://' + url
return url
def generate_email_qr(self, email, subject=None, body=None):
"""Genera QR code per email"""
if not self._is_valid_email(email):
raise ValueError("Email non valida")
mailto_string = f"mailto:{email}"
params = []
if subject:
params.append(f"subject={quote(subject)}")
if body:
params.append(f"body={quote(body)}")
if params:
mailto_string += "?" + "&".join(params)
return mailto_string
def generate_sms_qr(self, number, message=None):
"""Genera QR code per SMS"""
sms_string = f"sms:{number}"
if message:
sms_string += f"?body={quote(message)}"
return sms_string
def generate_phone_qr(self, number):
"""Genera QR code per chiamata telefonica"""
return f"tel:{number}"
def generate_vcard_qr(self, first_name, last_name, phone=None, email=None,
organization=None, url=None):
"""Genera QR code per biglietto da visita (vCard)"""
vcard = "BEGIN:VCARD\nVERSION:3.0\n"
vcard += f"FN:{first_name} {last_name}\n"
vcard += f"N:{last_name};{first_name};;;\n"
if phone:
vcard += f"TEL:{phone}\n"
if email:
vcard += f"EMAIL:{email}\n"
if organization:
vcard += f"ORG:{organization}\n"
if url:
vcard += f"URL:{url}\n"
vcard += "END:VCARD"
return vcard
def generate_event_qr(self, title, start_date, end_date=None, location=None, description=None):
"""Genera QR code per evento calendario"""
# Formato: YYYYMMDDTHHMMSS
start_formatted = start_date.strftime("%Y%m%dT%H%M%S")
end_formatted = end_date.strftime("%Y%m%dT%H%M%S") if end_date else start_formatted
vevent = "BEGIN:VEVENT\n"
vevent += f"SUMMARY:{title}\n"
vevent += f"DTSTART:{start_formatted}\n"
vevent += f"DTEND:{end_formatted}\n"
if location:
vevent += f"LOCATION:{location}\n"
if description:
vevent += f"DESCRIPTION:{description}\n"
vevent += "END:VEVENT"
return vevent
def generate_geo_qr(self, latitude, longitude, altitude=None):
"""Genera QR code per posizione geografica"""
if altitude:
return f"geo:{latitude},{longitude},{altitude}"
else:
return f"geo:{latitude},{longitude}"
def generate_whatsapp_qr(self, number, message=None):
"""Genera QR code per messaggio WhatsApp"""
# Rimuovi caratteri non numerici dal numero
clean_number = re.sub(r'[^\d+]', '', number)
wa_string = f"https://wa.me/{clean_number}"
if message:
wa_string += f"?text={quote(message)}"
return wa_string
def generate_text_qr(self, text):
"""Genera QR code per testo semplice"""
return text
def generate_raw_qr(self, content):
"""Genera QR code per contenuto personalizzato"""
return content
# === UTILITÀ ===
def _escape_wifi_chars(self, text):
"""Escape caratteri speciali per WiFi"""
if not text:
return ""
special_chars = ['\\', ';', ',', '"', ':']
escaped_text = text
for char in special_chars:
escaped_text = escaped_text.replace(char, f'\\{char}')
return escaped_text
def _is_valid_email(self, email):
"""Validazione email semplice"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
# === GENERATORE QR CODE ===
def create_qr_code(self, content, filename='qrcode.png',
error_correction=qrcode.constants.ERROR_CORRECT_M,
border=4, box_size=10, fill_color="black", back_color="white"):
"""Genera il QR code dal contenuto"""
try:
qr = qrcode.QRCode(
version=1,
error_correction=error_correction,
box_size=box_size,
border=border,
)
qr.add_data(content)
qr.make(fit=True)
img = qr.make_image(fill_color=fill_color, back_color=back_color)
img.save(filename)
return img, content
except Exception as e:
print(f"❌ Errore nella generazione del QR code: {e}")
return None, None
# === INTERFACCIA PRINCIPALE ===
def generate_qr(self, qr_type, filename='qrcode.png', show_details=True, **kwargs):
"""Metodo principale per generare QR code di qualsiasi tipo"""
try:
# Genera il contenuto in base al tipo
if qr_type == 'wifi':
content = self.generate_wifi_qr(**kwargs)
elif qr_type == 'url':
content = self.generate_url_qr(**kwargs)
elif qr_type == 'email':
content = self.generate_email_qr(**kwargs)
elif qr_type == 'sms':
content = self.generate_sms_qr(**kwargs)
elif qr_type == 'phone':
content = self.generate_phone_qr(**kwargs)
elif qr_type == 'vcard':
content = self.generate_vcard_qr(**kwargs)
elif qr_type == 'event':
content = self.generate_event_qr(**kwargs)
elif qr_type == 'geo':
content = self.generate_geo_qr(**kwargs)
elif qr_type == 'whatsapp':
content = self.generate_whatsapp_qr(**kwargs)
elif qr_type == 'text':
content = self.generate_text_qr(**kwargs)
elif qr_type == 'raw':
content = self.generate_raw_qr(**kwargs)
else:
raise ValueError(f"Tipo QR non supportato: {qr_type}")
# Genera il QR code
img, final_content = self.create_qr_code(content, filename)
if img and show_details:
print("✅ QR Code generato con successo!")
print(f"📁 File salvato: {filename}")
print(f"🏷️ Tipo: {self.qr_types.get(qr_type, qr_type)}")
print(f"📄 Contenuto: {final_content[:100]}{'...' if len(final_content) > 100 else ''}")
return img
except Exception as e:
print(f"❌ Errore: {e}")
return None
def main():
"""Interfaccia da riga di comando"""
parser = argparse.ArgumentParser(
description='Generatore QR Code Universale',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Tipi di QR Code supportati:
wifi - Connessione WiFi
url - URL/Link web
text - Testo semplice
email - Email
sms - SMS
phone - Numero telefono
vcard - Biglietto da visita
event - Evento calendario
geo - Posizione geografica
whatsapp - Messaggio WhatsApp
raw - Contenuto personalizzato
Esempi di utilizzo:
python qr_generator.py wifi -s "MiaRete" -p "password123"
python qr_generator.py url --url "https://google.com"
python qr_generator.py email --email "test@example.com" --subject "Ciao"
python qr_generator.py sms --number "+39123456789" --message "Ciao!"
python qr_generator.py vcard --first-name "Mario" --last-name "Rossi" --phone "+39123456789"
python qr_generator.py geo --latitude 45.4642 --longitude 9.1900
"""
)
parser.add_argument('type', choices=list(UniversalQRGenerator().qr_types.keys()),
help='Tipo di QR code da generare')
parser.add_argument('-o', '--output', default='qrcode.png',
help='Nome del file di output')
parser.add_argument('-q', '--quiet', action='store_true',
help='Non mostrare i dettagli')
# Argomenti per WiFi
wifi_group = parser.add_argument_group('WiFi')
wifi_group.add_argument('-s', '--ssid', help='Nome rete WiFi')
wifi_group.add_argument('-p', '--password', help='Password WiFi')
wifi_group.add_argument('--security', choices=['WPA', 'WEP', 'nopass'],
default='WPA', help='Tipo sicurezza WiFi')
wifi_group.add_argument('--hidden', action='store_true', help='Rete nascosta')
# Argomenti per URL
url_group = parser.add_argument_group('URL')
url_group.add_argument('--url', help='URL del sito web')
# Argomenti per email
email_group = parser.add_argument_group('Email')
email_group.add_argument('--email', help='Indirizzo email')
email_group.add_argument('--subject', help='Oggetto email')
email_group.add_argument('--body', help='Corpo email')
# Argomenti per SMS/Phone
comm_group = parser.add_argument_group('SMS/Telefono')
comm_group.add_argument('--number', help='Numero di telefono')
comm_group.add_argument('--message', help='Messaggio SMS/WhatsApp')
# Argomenti per vCard
vcard_group = parser.add_argument_group('vCard')
vcard_group.add_argument('--first-name', help='Nome')
vcard_group.add_argument('--last-name', help='Cognome')
vcard_group.add_argument('--organization', help='Organizzazione')
# Argomenti per geolocalizzazione
geo_group = parser.add_argument_group('Geolocalizzazione')
geo_group.add_argument('--latitude', type=float, help='Latitudine')
geo_group.add_argument('--longitude', type=float, help='Longitudine')
geo_group.add_argument('--altitude', type=float, help='Altitudine')
# Argomenti per testo/raw
text_group = parser.add_argument_group('Testo/Raw')
text_group.add_argument('--text', help='Testo da codificare')
text_group.add_argument('--content', help='Contenuto raw personalizzato')
args = parser.parse_args()
# Preparazione parametri per il generatore
generator = UniversalQRGenerator()
kwargs = {}
if args.type == 'wifi':
if not args.ssid:
print("❌ SSID obbligatorio per WiFi")
sys.exit(1)
kwargs = {
'ssid': args.ssid,
'password': args.password,
'security': args.security,
'hidden': args.hidden
}
elif args.type == 'url':
if not args.url:
print("❌ URL obbligatorio")
sys.exit(1)
kwargs = {'url': args.url}
elif args.type == 'email':
if not args.email:
print("❌ Email obbligatoria")
sys.exit(1)
kwargs = {
'email': args.email,
'subject': args.subject,
'body': args.body
}
elif args.type in ['sms', 'phone']:
if not args.number:
print("❌ Numero obbligatorio")
sys.exit(1)
kwargs = {'number': args.number}
if args.type == 'sms' and args.message:
kwargs['message'] = args.message
elif args.type == 'vcard':
if not (args.first_name and args.last_name):
print("❌ Nome e cognome obbligatori per vCard")
sys.exit(1)
kwargs = {
'first_name': args.first_name,
'last_name': args.last_name,
'phone': args.number,
'email': args.email,
'organization': args.organization
}
elif args.type == 'geo':
if args.latitude is None or args.longitude is None:
print("❌ Latitudine e longitudine obbligatorie")
sys.exit(1)
kwargs = {
'latitude': args.latitude,
'longitude': args.longitude,
'altitude': args.altitude
}
elif args.type == 'whatsapp':
if not args.number:
print("❌ Numero obbligatorio per WhatsApp")
sys.exit(1)
kwargs = {
'number': args.number,
'message': args.message
}
elif args.type == 'text':
if not args.text:
print("❌ Testo obbligatorio")
sys.exit(1)
kwargs = {'text': args.text}
elif args.type == 'raw':
if not args.content:
print("❌ Contenuto obbligatorio")
sys.exit(1)
kwargs = {'content': args.content}
# Genera il QR code
result = generator.generate_qr(
args.type,
filename=args.output,
show_details=not args.quiet,
**kwargs
)
sys.exit(0 if result else 1)
def interactive_mode():
"""Modalità interattiva"""
generator = UniversalQRGenerator()
print("🔧 Generatore QR Code Universale - Modalità Interattiva")
print("=" * 60)
# Selezione tipo
print("\n📋 Tipi di QR Code disponibili:")
types_list = list(generator.qr_types.items())
for i, (key, desc) in enumerate(types_list, 1):
print(f" {i:2d}. {desc}")
try:
choice = int(input(f"\nScegli (1-{len(types_list)}): "))
qr_type = types_list[choice - 1][0]
except (ValueError, IndexError):
print("❌ Scelta non valida")
return
print(f"\n🎯 Tipo selezionato: {generator.qr_types[qr_type]}")
# Input specifici per tipo
kwargs = {}
if qr_type == 'wifi':
kwargs['ssid'] = input("📶 SSID (nome rete): ")
kwargs['security'] = input("🔒 Sicurezza (WPA/WEP/nopass) [WPA]: ") or 'WPA'
if kwargs['security'] != 'nopass':
kwargs['password'] = input("🔑 Password: ")
kwargs['hidden'] = input("👁️ Rete nascosta? (s/N): ").lower().startswith('s')
elif qr_type == 'url':
kwargs['url'] = input("🌐 URL: ")
elif qr_type == 'email':
kwargs['email'] = input("📧 Email: ")
kwargs['subject'] = input("📝 Oggetto (opzionale): ") or None
kwargs['body'] = input("💬 Messaggio (opzionale): ") or None
elif qr_type == 'text':
kwargs['text'] = input("📄 Testo: ")
# Altri tipi...
# Nome file
filename = input("📁 Nome file [qrcode.png]: ") or "qrcode.png"
# Genera
print("\n⏳ Generazione in corso...")
generator.generate_qr(qr_type, filename=filename, **kwargs)
if __name__ == "__main__":
if len(sys.argv) == 1:
interactive_mode()
else:
main()