hello I only want to be a member

#42
by choaslord2010 - opened
No description provided.

this is a code can we add this in this app
import segno
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from PIL import Image, ImageTk
import io
import os
import socket
import requests
from pyzbar.pyzbar import decode
import webbrowser
import json

class QRCodeGenerator:
def init(self, root):
self.root = root
self.root.title("QR Code Generator & IP Tools")
self.root.geometry("750x950")
self.root.resizable(False, False)

    # Configure style
    self.root.configure(bg='#f0f0f0')

    # Variables
    self.current_qr = None
    self.qr_image = None
    self.location_data = None

    # Create UI
    self.create_widgets()

def create_widgets(self):
    # Title
    title_frame = tk.Frame(self.root, bg='#2c3e50', height=80)
    title_frame.pack(fill=tk.X)
    title_frame.pack_propagate(False)

    title_label = tk.Label(
        title_frame,
        text="QR Code Generator & IP Tools",
        font=("Arial", 22, "bold"),
        bg='#2c3e50',
        fg='white'
    )
    title_label.pack(expand=True)

    # Create Notebook for tabs
    self.notebook = ttk.Notebook(self.root)
    self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

    # Tab 1: QR Generator
    self.qr_generator_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.qr_generator_tab, text="QR Generator")
    self.create_qr_generator_tab()

    # Tab 2: QR Reader
    self.qr_reader_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.qr_reader_tab, text="QR Reader")
    self.create_qr_reader_tab()

    # Tab 3: IP Tools
    self.ip_tools_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.ip_tools_tab, text="IP Tools")
    self.create_ip_tools_tab()

def create_qr_generator_tab(self):
    """Original QR Generator UI"""
    # Input Frame
    input_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0', pady=20)
    input_frame.pack(fill=tk.X, padx=20)

    url_label = tk.Label(
        input_frame,
        text="Enter URL or Text:",
        font=("Arial", 12),
        bg='#f0f0f0'
    )
    url_label.pack(anchor=tk.W)

    self.url_entry = tk.Entry(
        input_frame,
        font=("Arial", 11),
        width=50,
        relief=tk.SOLID,
        borderwidth=1
    )
    self.url_entry.pack(fill=tk.X, pady=(5, 10))
    self.url_entry.bind('<Return>', lambda e: self.generate_qr())

    # Options Frame
    options_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0')
    options_frame.pack(fill=tk.X, padx=20, pady=(0, 10))

    # Error Correction Level
    error_label = tk.Label(
        options_frame,
        text="Error Correction:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    error_label.grid(row=0, column=0, sticky=tk.W, padx=(0, 10))

    self.error_level = tk.StringVar(value='M')
    error_combo = ttk.Combobox(
        options_frame,
        textvariable=self.error_level,
        values=['L (7%)', 'M (15%)', 'Q (25%)', 'H (30%)'],
        state='readonly',
        width=12
    )
    error_combo.grid(row=0, column=1, sticky=tk.W)

    # Scale
    scale_label = tk.Label(
        options_frame,
        text="Scale:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    scale_label.grid(row=0, column=2, sticky=tk.W, padx=(20, 10))

    self.scale_var = tk.IntVar(value=5)
    scale_spinbox = tk.Spinbox(
        options_frame,
        from_=1,
        to=20,
        textvariable=self.scale_var,
        width=8,
        font=("Arial", 10)
    )
    scale_spinbox.grid(row=0, column=3, sticky=tk.W)

    # Generate Button
    generate_btn = tk.Button(
        input_frame,
        text="Generate QR Code",
        command=self.generate_qr,
        bg='#3498db',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    generate_btn.pack(fill=tk.X)

    # QR Code Display Frame
    display_frame = tk.Frame(self.qr_generator_tab, bg='white', relief=tk.SOLID, borderwidth=1)
    display_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

    self.qr_label = tk.Label(
        display_frame,
        text="QR Code will appear here",
        font=("Arial", 12),
        bg='white',
        fg='#7f8c8d'
    )
    self.qr_label.pack(expand=True, pady=50)

    # Save Button Frame
    save_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0')
    save_frame.pack(fill=tk.X, padx=20, pady=(0, 20))

    self.save_btn = tk.Button(
        save_frame,
        text="Save QR Code",
        command=self.save_qr,
        bg='#27ae60',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10,
        state=tk.DISABLED
    )
    self.save_btn.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(0, 5))

    clear_btn = tk.Button(
        save_frame,
        text="Clear",
        command=self.clear_qr,
        bg='#e74c3c',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    clear_btn.pack(side=tk.RIGHT, expand=True, fill=tk.X, padx=(5, 0))

    # Status Label
    self.status_label = tk.Label(
        self.qr_generator_tab,
        text="",
        font=("Arial", 9),
        bg='#f0f0f0',
        fg='#7f8c8d'
    )
    self.status_label.pack(pady=(0, 10))

def create_qr_reader_tab(self):
    """QR Code Reader UI"""
    # Instructions
    inst_frame = tk.Frame(self.qr_reader_tab, bg='#f0f0f0', pady=20)
    inst_frame.pack(fill=tk.X, padx=20)

    inst_label = tk.Label(
        inst_frame,
        text="Upload a QR Code image to decode its content",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0'
    )
    inst_label.pack()

    # Upload Button
    upload_btn = tk.Button(
        inst_frame,
        text="Select QR Code Image",
        command=self.upload_qr_image,
        bg='#9b59b6',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    upload_btn.pack(pady=10)

    # Display Frame for uploaded image
    self.reader_display_frame = tk.Frame(self.qr_reader_tab, bg='white', relief=tk.SOLID, borderwidth=1, height=300)
    self.reader_display_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
    self.reader_display_frame.pack_propagate(False)

    self.reader_image_label = tk.Label(
        self.reader_display_frame,
        text="No image loaded",
        font=("Arial", 12),
        bg='white',
        fg='#7f8c8d'
    )
    self.reader_image_label.pack(expand=True)

    # Result Frame
    result_frame = tk.Frame(self.qr_reader_tab, bg='#f0f0f0', pady=10)
    result_frame.pack(fill=tk.BOTH, expand=True, padx=20)

    result_label = tk.Label(
        result_frame,
        text="Decoded Content:",
        font=("Arial", 11, "bold"),
        bg='#f0f0f0'
    )
    result_label.pack(anchor=tk.W)

    self.reader_result_text = tk.Text(
        result_frame,
        font=("Arial", 10),
        height=6,
        wrap=tk.WORD,
        relief=tk.SOLID,
        borderwidth=1
    )
    self.reader_result_text.pack(fill=tk.BOTH, expand=True, pady=5)

    # Copy Button
    copy_btn = tk.Button(
        result_frame,
        text="Copy to Clipboard",
        command=self.copy_decoded_content,
        bg='#16a085',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    copy_btn.pack(fill=tk.X, pady=5)

def create_ip_tools_tab(self):
    """IP Tools UI with Advanced Geolocation"""
    # Scrollable canvas for IP tools
    canvas = tk.Canvas(self.ip_tools_tab, bg='#f0f0f0', highlightthickness=0)
    scrollbar = ttk.Scrollbar(self.ip_tools_tab, orient="vertical", command=canvas.yview)
    scrollable_frame = tk.Frame(canvas, bg='#f0f0f0')

    scrollable_frame.bind(
        "<Configure>",
        lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
    )

    canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
    canvas.configure(yscrollcommand=scrollbar.set)

    # My IP Location Section
    ip_location_frame = tk.LabelFrame(
        scrollable_frame,
        text="🌍 Advanced IP Geolocation & Mapping",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    ip_location_frame.pack(fill=tk.X, padx=20, pady=10)

    get_location_btn = tk.Button(
        ip_location_frame,
        text="πŸ” Get Precise Location",
        command=self.get_advanced_ip_location,
        bg='#e67e22',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    get_location_btn.pack(fill=tk.X, padx=10)

    self.ip_location_text = tk.Text(
        ip_location_frame,
        font=("Courier", 9),
        height=12,
        wrap=tk.WORD,
        relief=tk.SOLID,
        borderwidth=1,
        state=tk.DISABLED
    )
    self.ip_location_text.pack(fill=tk.X, padx=10, pady=10)

    # Map buttons frame
    map_buttons_frame = tk.Frame(ip_location_frame, bg='#f0f0f0')
    map_buttons_frame.pack(fill=tk.X, padx=10, pady=(0, 10))

    self.open_google_maps_btn = tk.Button(
        map_buttons_frame,
        text="πŸ“ Open in Google Maps",
        command=lambda: self.open_in_maps('google'),
        bg='#4285F4',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED
    )
    self.open_google_maps_btn.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(0, 5))

    self.open_osm_btn = tk.Button(
        map_buttons_frame,
        text="πŸ—ΊοΈ Open in OpenStreetMap",
        command=lambda: self.open_in_maps('osm'),
        bg='#7EBC6F',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED
    )
    self.open_osm_btn.pack(side=tk.RIGHT, expand=True, fill=tk.X, padx=(5, 0))

    # Additional info button
    self.additional_info_btn = tk.Button(
        ip_location_frame,
        text="πŸ“Š Get Additional Network Info",
        command=self.get_additional_network_info,
        bg='#8e44ad',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED,
        padx=20,
        pady=8
    )
    self.additional_info_btn.pack(fill=tk.X, padx=10, pady=(0, 10))

    # URL to IP Section
    url_to_ip_frame = tk.LabelFrame(
        scrollable_frame,
        text="πŸ”— URL to IP Address",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    url_to_ip_frame.pack(fill=tk.X, padx=20, pady=10)

    url_input_label = tk.Label(
        url_to_ip_frame,
        text="Enter URL or Domain:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    url_input_label.pack(anchor=tk.W, padx=10)

    self.url_to_ip_entry = tk.Entry(
        url_to_ip_frame,
        font=("Arial", 11),
        relief=tk.SOLID,
        borderwidth=1
    )
    self.url_to_ip_entry.pack(fill=tk.X, padx=10, pady=5)
    self.url_to_ip_entry.bind('<Return>', lambda e: self.convert_url_to_ip())

    convert_url_btn = tk.Button(
        url_to_ip_frame,
        text="Convert to IP",
        command=self.convert_url_to_ip,
        bg='#3498db',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    convert_url_btn.pack(fill=tk.X, padx=10, pady=5)

    self.url_to_ip_result = tk.Label(
        url_to_ip_frame,
        text="",
        font=("Arial", 10),
        bg='#f0f0f0',
        fg='#27ae60',
        wraplength=680
    )
    self.url_to_ip_result.pack(padx=10, pady=5)

    # IP to URL Section
    ip_to_url_frame = tk.LabelFrame(
        scrollable_frame,
        text="πŸ”„ IP Address to URL (Reverse DNS)",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    ip_to_url_frame.pack(fill=tk.X, padx=20, pady=10)

    ip_input_label = tk.Label(
        ip_to_url_frame,
        text="Enter IP Address:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    ip_input_label.pack(anchor=tk.W, padx=10)

    self.ip_to_url_entry = tk.Entry(
        ip_to_url_frame,
        font=("Arial", 11),
        relief=tk.SOLID,
        borderwidth=1
    )
    self.ip_to_url_entry.pack(fill=tk.X, padx=10, pady=5)
    self.ip_to_url_entry.bind('<Return>', lambda e: self.convert_ip_to_url())

    convert_ip_btn = tk.Button(
        ip_to_url_frame,
        text="Convert to URL",
        command=self.convert_ip_to_url,
        bg='#27ae60',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    convert_ip_btn.pack(fill=tk.X, padx=10, pady=5)

    self.ip_to_url_result = tk.Label(
        ip_to_url_frame,
        text="",
        font=("Arial", 10),
        bg='#f0f0f0',
        fg='#27ae60',
        wraplength=680
    )
    self.ip_to_url_result.pack(padx=10, pady=5)

    canvas.pack(side="left", fill="both", expand=True)
    scrollbar.pack(side="right", fill="y")

# QR Generator Functions
def get_error_level(self):
    """Convert error level string to segno error level"""
    level_map = {
        'L (7%)': 'L',
        'M (15%)': 'M',
        'Q (25%)': 'Q',
        'H (30%)': 'H'
    }
    return level_map.get(self.error_level.get(), 'M')

def generate_qr(self):
    """Generate QR code from input URL/text"""
    url = self.url_entry.get().strip()

    if not url:
        messagebox.showwarning("Input Required", "Please enter a URL or text to generate QR code!")
        return

    try:
        error_level = self.get_error_level()
        scale = self.scale_var.get()

        self.current_qr = segno.make(url, error=error_level)

        buffer = io.BytesIO()
        self.current_qr.save(buffer, kind='png', scale=scale, border=2)
        buffer.seek(0)

        img = Image.open(buffer)

        display_size = 400
        if img.width > display_size or img.height > display_size:
            img.thumbnail((display_size, display_size), Image.Resampling.LANCZOS)

        self.qr_image = ImageTk.PhotoImage(img)
        self.qr_label.configure(image=self.qr_image, text="")

        self.save_btn.configure(state=tk.NORMAL)

        try:
            version = self.current_qr.version
            self.status_label.configure(text=f"QR Code generated successfully! Version: {version}")
        except:
            self.status_label.configure(text="QR Code generated successfully!")

    except Exception as e:
        messagebox.showerror("Error", f"Failed to generate QR code:\n{str(e)}")

def save_qr(self):
    """Save the generated QR code to file"""
    if self.current_qr is None:
        messagebox.showwarning("No QR Code", "Please generate a QR code first!")
        return

    try:
        file_path = filedialog.asksaveasfilename(
            defaultextension=".png",
            filetypes=[
                ("PNG files", "*.png"),
                ("SVG files", "*.svg"),
                ("PDF files", "*.pdf"),
                ("EPS files", "*.eps"),
                ("All files", "*.*")
            ],
            title="Save QR Code"
        )

        if file_path:
            _, ext = os.path.splitext(file_path)
            ext = ext.lower().replace('.', '')

            if not ext:
                ext = 'png'
                file_path += '.png'

            scale = self.scale_var.get()

            if ext in ['png', 'jpg', 'jpeg']:
                self.current_qr.save(file_path, kind=ext, scale=scale, border=2)
            elif ext == 'svg':
                self.current_qr.save(file_path, kind='svg', scale=scale, border=2)
            elif ext == 'pdf':
                self.current_qr.save(file_path, kind='pdf', scale=scale, border=2)
            elif ext == 'eps':
                self.current_qr.save(file_path, kind='eps', scale=scale, border=2)
            else:
                self.current_qr.save(file_path, kind='png', scale=scale, border=2)

            self.status_label.configure(
                text=f"QR Code saved successfully to: {os.path.basename(file_path)}"
            )
            messagebox.showinfo("Success", f"QR Code saved successfully!\n\n{file_path}")

    except Exception as e:
        messagebox.showerror("Save Error", f"Failed to save QR code:\n{str(e)}")

def clear_qr(self):
    """Clear the current QR code and reset the form"""
    self.url_entry.delete(0, tk.END)
    self.current_qr = None
    self.qr_image = None
    self.qr_label.configure(image='', text="QR Code will appear here")
    self.save_btn.configure(state=tk.DISABLED)
    self.status_label.configure(text="")

# QR Reader Functions
def upload_qr_image(self):
    """Upload and decode QR code image"""
    file_path = filedialog.askopenfilename(
        title="Select QR Code Image",
        filetypes=[
            ("Image files", "*.png *.jpg *.jpeg *.bmp *.gif"),
            ("All files", "*.*")
        ]
    )

    if not file_path:
        return

    try:
        # Load and display image
        img = Image.open(file_path)
        
        # Resize for display
        display_size = 250
        img_copy = img.copy()
        img_copy.thumbnail((display_size, display_size), Image.Resampling.LANCZOS)
        
        self.reader_image = ImageTk.PhotoImage(img_copy)
        self.reader_image_label.configure(image=self.reader_image, text="")

        # Decode QR code
        decoded_objects = decode(img)

        self.reader_result_text.configure(state=tk.NORMAL)
        self.reader_result_text.delete(1.0, tk.END)

        if decoded_objects:
            for obj in decoded_objects:
                decoded_data = obj.data.decode('utf-8')
                qr_type = obj.type
                self.reader_result_text.insert(tk.END, f"Type: {qr_type}\n")
                self.reader_result_text.insert(tk.END, f"Content: {decoded_data}\n")
                
                # If it's a URL, show additional info
                if decoded_data.startswith(('http://', 'https://', 'www.')):
                    self.reader_result_text.insert(tk.END, f"\nβœ“ Valid URL detected\n")
        else:
            self.reader_result_text.insert(tk.END, "No QR code found in the image.")

        self.reader_result_text.configure(state=tk.DISABLED)

    except Exception as e:
        messagebox.showerror("Error", f"Failed to read QR code:\n{str(e)}")

def copy_decoded_content(self):
    """Copy decoded content to clipboard"""
    content = self.reader_result_text.get(1.0, tk.END).strip()
    if content and content != "No QR code found in the image.":
        self.root.clipboard_clear()
        self.root.clipboard_append(content)
        messagebox.showinfo("Copied", "Content copied to clipboard!")
    else:
        messagebox.showwarning("No Content", "No content to copy!")

# Advanced IP Tools Functions
def get_advanced_ip_location(self):
    """Get advanced IP location with multiple data sources"""
    self.ip_location_text.configure(state=tk.NORMAL)
    self.ip_location_text.delete(1.0, tk.END)
    self.ip_location_text.insert(tk.END, "πŸ”„ Fetching precise geolocation data...\n")
    self.root.update()

    # Try multiple APIs for best accuracy
    apis = [
        self.try_ipapi_co,
        self.try_ip_api_com,
        self.try_ipinfo_io,
    ]

    for api_func in apis:
        try:
            data = api_func()
            if data:
                self.location_data = data
                self.display_location_data(data)
                
                # Enable map buttons
                self.open_google_maps_btn.configure(state=tk.NORMAL)
                self.open_osm_btn.configure(state=tk.NORMAL)
                self.additional_info_btn.configure(state=tk.NORMAL)
                return
        except Exception as e:
            continue

    # If all APIs fail
    self.ip_location_text.delete(1.0, tk.END)
    self.ip_location_text.insert(tk.END, "❌ Unable to fetch location data.\n")
    self.ip_location_text.insert(tk.END, "Please check your internet connection.")
    self.ip_location_text.configure(state=tk.DISABLED)

def display_location_data(self, data):
    """Display formatted location data"""
    self.ip_location_text.delete(1.0, tk.END)
    
    info = f"""╔══════════════════════════════════════════╗

β•‘ NETWORK & LOCATION INFO β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

🌐 IP ADDRESS
{data.get('ip', 'N/A')}

πŸ“ PRECISE LOCATION
City: {data.get('city', 'N/A')}
Region: {data.get('region', 'N/A')}
Country: {data.get('country_name', 'N/A')} ({data.get('country_code', 'N/A')})
Postal: {data.get('postal', 'N/A')}

πŸ—ΊοΈ GPS COORDINATES
Latitude: {data.get('latitude', 'N/A')}
Longitude: {data.get('longitude', 'N/A')}
Accuracy: ~{data.get('accuracy', '100-1000')}m radius

🏒 ISP & NETWORK
Provider: {data.get('isp', 'N/A')}
Organization: {data.get('org', 'N/A')}
ASN: {data.get('asn', 'N/A')}

⏰ TIMEZONE
Timezone: {data.get('timezone', 'N/A')}
UTC Offset: {data.get('utc_offset', 'N/A')}

🌍 ADDITIONAL INFO
Continent: {data.get('continent', 'N/A')}
Currency: {data.get('currency', 'N/A')}
Languages: {data.get('languages', 'N/A')}

"""
self.ip_location_text.insert(tk.END, info)
self.ip_location_text.configure(state=tk.DISABLED)

def try_ipapi_co(self):
    """Try ipapi.co API - Most comprehensive"""
    response = requests.get('https://ipapi.co/json/', timeout=10)
    if response.status_code == 200:
        data = response.json()
        return {
            'ip': data.get('ip'),
            'city': data.get('city'),
            'region': data.get('region'),
            'country_name': data.get('country_name'),
            'country_code': data.get('country_code'),
            'postal': data.get('postal'),
            'latitude': data.get('latitude'),
            'longitude': data.get('longitude'),
            'timezone': data.get('timezone'),
            'utc_offset': data.get('utc_offset'),
            'isp': data.get('org'),
            'org': data.get('org'),
            'asn': data.get('asn'),
            'continent': data.get('continent_code'),
            'currency': data.get('currency'),
            'languages': data.get('languages'),
            'accuracy': '100-500'
        }
    return None

def try_ip_api_com(self):
    """Try ip-api.com API"""
    response = requests.get('http://ip-api.com/json/?fields=66846719', timeout=10)
    if response.status_code == 200:
        data = response.json()
        if data.get('status') == 'success':
            return {
                'ip': data.get('query'),
                'city': data.get('city'),
                'region': data.get('regionName'),
                'country_name': data.get('country'),
                'country_code': data.get('countryCode'),
                'postal': data.get('zip'),
                'latitude': data.get('lat'),
                'longitude': data.get('lon'),
                'timezone': data.get('timezone'),
                'utc_offset': data.get('offset'),
                'isp': data.get('isp'),
                'org': data.get('org'),
                'asn': data.get('as'),
                'continent': data.get('continent'),
                'currency': data.get('currency'),
                'languages': 'N/A',
                'accuracy': '500-1000'
            }
    return None

def try_ipinfo_io(self):
    """Try ipinfo.io API"""
    response = requests.get('https://ipinfo.io/json', timeout=10)
    if response.status_code == 200:
        data = response.json()
        loc = data.get('loc', ',').split(',')
        return {
            'ip': data.get('ip'),
            'city': data.get('city'),
            'region': data.get('region'),
            'country_name': data.get('country'),
            'country_code': data.get('country'),
            'postal': data.get('postal'),
            'latitude': loc[0] if len(loc) > 0 else 'N/A',
            'longitude': loc[1] if len(loc) > 1 else 'N/A',
            'timezone': data.get('timezone'),
            'utc_offset': 'N/A',
            'isp': data.get('org'),
            'org': data.get('org'),
            'asn': 'N/A',
            'continent': 'N/A',
            'currency': 'N/A',
            'languages': 'N/A',
            'accuracy': '1000-5000'
        }
    return None

def open_in_maps(self, map_type):
    """Open location in map service"""
    if not self.location_data:
        messagebox.showwarning("No Location", "Please get location data first!")
        return

    lat = self.location_data.get('latitude')
    lon = self.location_data.get('longitude')

    if not lat or not lon or lat == 'N/A' or lon == 'N/A':
        messagebox.showwarning("No Coordinates", "GPS coordinates not available!")
        return

    try:
        if map_type == 'google':
            # Open in Google Maps
            url = f"https://www.google.com/maps?q={lat},{lon}&z=15"
            webbrowser.open(url)
        elif map_type == 'osm':
            # Open in OpenStreetMap
            url = f"https://www.openstreetmap.org/?mlat={lat}&mlon={lon}&zoom=15"
            webbrowser.open(url)
    except Exception as e:
        messagebox.showerror("Error", f"Failed to open map:\n{str(e)}")

def get_additional_network_info(self):
    """Get additional network and routing information"""
    if not self.location_data:
        messagebox.showwarning("No Data", "Please get location data first!")
        return

    ip = self.location_data.get('ip')
    if not ip or ip == 'N/A':
        messagebox.showwarning("No IP", "IP address not available!")
        return

    try:
        # Get additional info
        info_window = tk.Toplevel(self.root)
        info_window.title("Additional Network Information")
        info_window.geometry("600x500")
        info_window.configure(bg='#f0f0f0')

        title_label = tk.Label(
            info_window,
            text="πŸ” Advanced Network Analysis",
            font=("Arial", 14, "bold"),
            bg='#2c3e50',
            fg='white',
            pady=15
        )
        title_label.pack(fill=tk.X)

        info_text = tk.Text(
            info_window,
            font=("Courier", 9),
            wrap=tk.WORD,
            relief=tk.SOLID,
            borderwidth=1
        )
        info_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        info_text.insert(tk.END, f"Analyzing IP: {ip}\n")
        info_text.insert(tk.END, "=" * 60 + "\n\n")

        # DNS Information
        try:
            hostname = socket.gethostbyaddr(ip)[0]
            info_text.insert(tk.END, f"πŸ”Ή Reverse DNS:\n   {hostname}\n\n")
        except:
            info_text.insert(tk.END, f"πŸ”Ή Reverse DNS:\n   No hostname found\n\n")

        # Try to get more info from ipapi.co
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=10)
            if response.status_code == 200:
                data = response.json()
                
                info_text.insert(tk.END, "πŸ”Ή Network Details:\n")
                info_text.insert(tk.END, f"   ASN: {data.get('asn', 'N/A')}\n")
                info_text.insert(tk.END, f"   Network: {data.get('network', 'N/A')}\n")
                info_text.insert(tk.END, f"   Version: IPv{data.get('version', 'N/A')}\n\n")
                
                info_text.insert(tk.END, "πŸ”Ή Geographic Details:\n")
                info_text.insert(tk.END, f"   Capital: {data.get('country_capital', 'N/A')}\n")
                info_text.insert(tk.END, f"   Area: {data.get('country_area', 'N/A')} kmΒ²\n")
                info_text.insert(tk.END, f"   Population: {data.get('country_population', 'N/A')}\n")
                info_text.insert(tk.END, f"   Calling Code: +{data.get('country_calling_code', 'N/A')}\n\n")
                
                info_text.insert(tk.END, "πŸ”Ή Connection Type:\n")
                info_text.insert(tk.END, f"   Type: {data.get('connection_type', 'N/A')}\n\n")
                
                if data.get('threat'):
                    threat_data = data.get('threat', {})
                    info_text.insert(tk.END, "πŸ”Ή Security Information:\n")
                    info_text.insert(tk.END, f"   Tor Exit: {threat_data.get('is_tor', False)}\n")
                    info_text.insert(tk.END, f"   Proxy: {threat_data.get('is_proxy', False)}\n")
                    info_text.insert(tk.END, f"   Anonymous: {threat_data.get('is_anonymous', False)}\n\n")
        except:
            info_text.insert(tk.END, "Additional details unavailable\n")

        info_text.configure(state=tk.DISABLED)

        close_btn = tk.Button(
            info_window,
            text="Close",
            command=info_window.destroy,
            bg='#e74c3c',
            fg='white',
            font=("Arial", 11, "bold"),
            relief=tk.FLAT,
            cursor='hand2',
            pady=10
        )
        close_btn.pack(fill=tk.X, padx=10, pady=(0, 10))

    except Exception as e:
        messagebox.showerror("Error", f"Failed to get additional info:\n{str(e)}")

def convert_url_to_ip(self):
    """Convert URL/domain to IP address with additional info"""
    url = self.url_to_ip_entry.get().strip()
    
    if not url:
        messagebox.showwarning("Input Required", "Please enter a URL or domain!")
        return

    try:
        # Remove protocol if present
        domain = url.replace('https://', '').replace('http://', '').split('/')[0]
        
        # Get IP address
        ip_address = socket.gethostbyname(domain)
        
        # Try to get geolocation for this IP
        try:
            response = requests.get(f'https://ipapi.co/{ip_address}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                location_info = f"\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}"
                org_info = f"\n🏒 Organization: {data.get('org', 'N/A')}"
            else:
                location_info = ""
                org_info = ""
        except:
            location_info = ""
            org_info = ""
        
        self.url_to_ip_result.configure(
            text=f"βœ“ Domain: {domain}\nβœ“ IP Address: {ip_address}{location_info}{org_info}",
            fg='#27ae60'
        )

    except socket.gaierror:
        self.url_to_ip_result.configure(
            text=f"βœ— Could not resolve domain: {domain}\n(Check spelling or DNS availability)",
            fg='#e74c3c'
        )
    except Exception as e:
        self.url_to_ip_result.configure(
            text=f"βœ— Error: {str(e)}",
            fg='#e74c3c'
        )

def convert_ip_to_url(self):
    """Convert IP address to URL using reverse DNS with geolocation"""
    ip = self.ip_to_url_entry.get().strip()
    
    if not ip:
        messagebox.showwarning("Input Required", "Please enter an IP address!")
        return

    try:
        # Reverse DNS lookup
        hostname = socket.gethostbyaddr(ip)[0]
        
        # Try to get location info
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                location_info = f"\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}"
                org_info = f"\n🏒 Organization: {data.get('org', 'N/A')}"
            else:
                location_info = ""
                org_info = ""
        except:
            location_info = ""
            org_info = ""
        
        self.ip_to_url_result.configure(
            text=f"βœ“ IP: {ip}\nβœ“ Hostname: {hostname}{location_info}{org_info}",
            fg='#27ae60'
        )

    except socket.herror:
        # Even if no hostname, try to show location
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                self.ip_to_url_result.configure(
                    text=f"βœ“ IP: {ip}\n⚠️ No hostname found\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}\n🏒 Organization: {data.get('org', 'N/A')}",
                    fg='#f39c12'
                )
            else:
                self.ip_to_url_result.configure(
                    text=f"βœ— No hostname found for IP: {ip}",
                    fg='#e74c3c'
                )
        except:
            self.ip_to_url_result.configure(
                text=f"βœ— No hostname found for IP: {ip}",
                fg='#e74c3c'
            )
    except Exception as e:
        self.ip_to_url_result.configure(
            text=f"βœ— Error: {str(e)}",
            fg='#e74c3c'
        )

def main():
"""Main function to run the application"""
root = tk.Tk()
app = QRCodeGenerator(root)
root.mainloop()

if name == "main":
main()

choaslord2010 changed pull request status to open

this is a code can we add this in this app
import segno
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from PIL import Image, ImageTk
import io
import os
import socket
import requests
from pyzbar.pyzbar import decode
import webbrowser
import json

class QRCodeGenerator:
def init(self, root):
self.root = root
self.root.title("QR Code Generator & IP Tools")
self.root.geometry("750x950")
self.root.resizable(False, False)

    # Configure style
    self.root.configure(bg='#f0f0f0')

    # Variables
    self.current_qr = None
    self.qr_image = None
    self.location_data = None

    # Create UI
    self.create_widgets()

def create_widgets(self):
    # Title
    title_frame = tk.Frame(self.root, bg='#2c3e50', height=80)
    title_frame.pack(fill=tk.X)
    title_frame.pack_propagate(False)

    title_label = tk.Label(
        title_frame,
        text="QR Code Generator & IP Tools",
        font=("Arial", 22, "bold"),
        bg='#2c3e50',
        fg='white'
    )
    title_label.pack(expand=True)

    # Create Notebook for tabs
    self.notebook = ttk.Notebook(self.root)
    self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

    # Tab 1: QR Generator
    self.qr_generator_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.qr_generator_tab, text="QR Generator")
    self.create_qr_generator_tab()

    # Tab 2: QR Reader
    self.qr_reader_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.qr_reader_tab, text="QR Reader")
    self.create_qr_reader_tab()

    # Tab 3: IP Tools
    self.ip_tools_tab = tk.Frame(self.notebook, bg='#f0f0f0')
    self.notebook.add(self.ip_tools_tab, text="IP Tools")
    self.create_ip_tools_tab()

def create_qr_generator_tab(self):
    """Original QR Generator UI"""
    # Input Frame
    input_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0', pady=20)
    input_frame.pack(fill=tk.X, padx=20)

    url_label = tk.Label(
        input_frame,
        text="Enter URL or Text:",
        font=("Arial", 12),
        bg='#f0f0f0'
    )
    url_label.pack(anchor=tk.W)

    self.url_entry = tk.Entry(
        input_frame,
        font=("Arial", 11),
        width=50,
        relief=tk.SOLID,
        borderwidth=1
    )
    self.url_entry.pack(fill=tk.X, pady=(5, 10))
    self.url_entry.bind('<Return>', lambda e: self.generate_qr())

    # Options Frame
    options_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0')
    options_frame.pack(fill=tk.X, padx=20, pady=(0, 10))

    # Error Correction Level
    error_label = tk.Label(
        options_frame,
        text="Error Correction:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    error_label.grid(row=0, column=0, sticky=tk.W, padx=(0, 10))

    self.error_level = tk.StringVar(value='M')
    error_combo = ttk.Combobox(
        options_frame,
        textvariable=self.error_level,
        values=['L (7%)', 'M (15%)', 'Q (25%)', 'H (30%)'],
        state='readonly',
        width=12
    )
    error_combo.grid(row=0, column=1, sticky=tk.W)

    # Scale
    scale_label = tk.Label(
        options_frame,
        text="Scale:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    scale_label.grid(row=0, column=2, sticky=tk.W, padx=(20, 10))

    self.scale_var = tk.IntVar(value=5)
    scale_spinbox = tk.Spinbox(
        options_frame,
        from_=1,
        to=20,
        textvariable=self.scale_var,
        width=8,
        font=("Arial", 10)
    )
    scale_spinbox.grid(row=0, column=3, sticky=tk.W)

    # Generate Button
    generate_btn = tk.Button(
        input_frame,
        text="Generate QR Code",
        command=self.generate_qr,
        bg='#3498db',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    generate_btn.pack(fill=tk.X)

    # QR Code Display Frame
    display_frame = tk.Frame(self.qr_generator_tab, bg='white', relief=tk.SOLID, borderwidth=1)
    display_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

    self.qr_label = tk.Label(
        display_frame,
        text="QR Code will appear here",
        font=("Arial", 12),
        bg='white',
        fg='#7f8c8d'
    )
    self.qr_label.pack(expand=True, pady=50)

    # Save Button Frame
    save_frame = tk.Frame(self.qr_generator_tab, bg='#f0f0f0')
    save_frame.pack(fill=tk.X, padx=20, pady=(0, 20))

    self.save_btn = tk.Button(
        save_frame,
        text="Save QR Code",
        command=self.save_qr,
        bg='#27ae60',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10,
        state=tk.DISABLED
    )
    self.save_btn.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(0, 5))

    clear_btn = tk.Button(
        save_frame,
        text="Clear",
        command=self.clear_qr,
        bg='#e74c3c',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    clear_btn.pack(side=tk.RIGHT, expand=True, fill=tk.X, padx=(5, 0))

    # Status Label
    self.status_label = tk.Label(
        self.qr_generator_tab,
        text="",
        font=("Arial", 9),
        bg='#f0f0f0',
        fg='#7f8c8d'
    )
    self.status_label.pack(pady=(0, 10))

def create_qr_reader_tab(self):
    """QR Code Reader UI"""
    # Instructions
    inst_frame = tk.Frame(self.qr_reader_tab, bg='#f0f0f0', pady=20)
    inst_frame.pack(fill=tk.X, padx=20)

    inst_label = tk.Label(
        inst_frame,
        text="Upload a QR Code image to decode its content",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0'
    )
    inst_label.pack()

    # Upload Button
    upload_btn = tk.Button(
        inst_frame,
        text="Select QR Code Image",
        command=self.upload_qr_image,
        bg='#9b59b6',
        fg='white',
        font=("Arial", 12, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    upload_btn.pack(pady=10)

    # Display Frame for uploaded image
    self.reader_display_frame = tk.Frame(self.qr_reader_tab, bg='white', relief=tk.SOLID, borderwidth=1, height=300)
    self.reader_display_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
    self.reader_display_frame.pack_propagate(False)

    self.reader_image_label = tk.Label(
        self.reader_display_frame,
        text="No image loaded",
        font=("Arial", 12),
        bg='white',
        fg='#7f8c8d'
    )
    self.reader_image_label.pack(expand=True)

    # Result Frame
    result_frame = tk.Frame(self.qr_reader_tab, bg='#f0f0f0', pady=10)
    result_frame.pack(fill=tk.BOTH, expand=True, padx=20)

    result_label = tk.Label(
        result_frame,
        text="Decoded Content:",
        font=("Arial", 11, "bold"),
        bg='#f0f0f0'
    )
    result_label.pack(anchor=tk.W)

    self.reader_result_text = tk.Text(
        result_frame,
        font=("Arial", 10),
        height=6,
        wrap=tk.WORD,
        relief=tk.SOLID,
        borderwidth=1
    )
    self.reader_result_text.pack(fill=tk.BOTH, expand=True, pady=5)

    # Copy Button
    copy_btn = tk.Button(
        result_frame,
        text="Copy to Clipboard",
        command=self.copy_decoded_content,
        bg='#16a085',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    copy_btn.pack(fill=tk.X, pady=5)

def create_ip_tools_tab(self):
    """IP Tools UI with Advanced Geolocation"""
    # Scrollable canvas for IP tools
    canvas = tk.Canvas(self.ip_tools_tab, bg='#f0f0f0', highlightthickness=0)
    scrollbar = ttk.Scrollbar(self.ip_tools_tab, orient="vertical", command=canvas.yview)
    scrollable_frame = tk.Frame(canvas, bg='#f0f0f0')

    scrollable_frame.bind(
        "<Configure>",
        lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
    )

    canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
    canvas.configure(yscrollcommand=scrollbar.set)

    # My IP Location Section
    ip_location_frame = tk.LabelFrame(
        scrollable_frame,
        text="🌍 Advanced IP Geolocation & Mapping",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    ip_location_frame.pack(fill=tk.X, padx=20, pady=10)

    get_location_btn = tk.Button(
        ip_location_frame,
        text="πŸ” Get Precise Location",
        command=self.get_advanced_ip_location,
        bg='#e67e22',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=10
    )
    get_location_btn.pack(fill=tk.X, padx=10)

    self.ip_location_text = tk.Text(
        ip_location_frame,
        font=("Courier", 9),
        height=12,
        wrap=tk.WORD,
        relief=tk.SOLID,
        borderwidth=1,
        state=tk.DISABLED
    )
    self.ip_location_text.pack(fill=tk.X, padx=10, pady=10)

    # Map buttons frame
    map_buttons_frame = tk.Frame(ip_location_frame, bg='#f0f0f0')
    map_buttons_frame.pack(fill=tk.X, padx=10, pady=(0, 10))

    self.open_google_maps_btn = tk.Button(
        map_buttons_frame,
        text="πŸ“ Open in Google Maps",
        command=lambda: self.open_in_maps('google'),
        bg='#4285F4',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED
    )
    self.open_google_maps_btn.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(0, 5))

    self.open_osm_btn = tk.Button(
        map_buttons_frame,
        text="πŸ—ΊοΈ Open in OpenStreetMap",
        command=lambda: self.open_in_maps('osm'),
        bg='#7EBC6F',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED
    )
    self.open_osm_btn.pack(side=tk.RIGHT, expand=True, fill=tk.X, padx=(5, 0))

    # Additional info button
    self.additional_info_btn = tk.Button(
        ip_location_frame,
        text="πŸ“Š Get Additional Network Info",
        command=self.get_additional_network_info,
        bg='#8e44ad',
        fg='white',
        font=("Arial", 10, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        state=tk.DISABLED,
        padx=20,
        pady=8
    )
    self.additional_info_btn.pack(fill=tk.X, padx=10, pady=(0, 10))

    # URL to IP Section
    url_to_ip_frame = tk.LabelFrame(
        scrollable_frame,
        text="πŸ”— URL to IP Address",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    url_to_ip_frame.pack(fill=tk.X, padx=20, pady=10)

    url_input_label = tk.Label(
        url_to_ip_frame,
        text="Enter URL or Domain:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    url_input_label.pack(anchor=tk.W, padx=10)

    self.url_to_ip_entry = tk.Entry(
        url_to_ip_frame,
        font=("Arial", 11),
        relief=tk.SOLID,
        borderwidth=1
    )
    self.url_to_ip_entry.pack(fill=tk.X, padx=10, pady=5)
    self.url_to_ip_entry.bind('<Return>', lambda e: self.convert_url_to_ip())

    convert_url_btn = tk.Button(
        url_to_ip_frame,
        text="Convert to IP",
        command=self.convert_url_to_ip,
        bg='#3498db',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    convert_url_btn.pack(fill=tk.X, padx=10, pady=5)

    self.url_to_ip_result = tk.Label(
        url_to_ip_frame,
        text="",
        font=("Arial", 10),
        bg='#f0f0f0',
        fg='#27ae60',
        wraplength=680
    )
    self.url_to_ip_result.pack(padx=10, pady=5)

    # IP to URL Section
    ip_to_url_frame = tk.LabelFrame(
        scrollable_frame,
        text="πŸ”„ IP Address to URL (Reverse DNS)",
        font=("Arial", 12, "bold"),
        bg='#f0f0f0',
        fg='#2c3e50',
        pady=10
    )
    ip_to_url_frame.pack(fill=tk.X, padx=20, pady=10)

    ip_input_label = tk.Label(
        ip_to_url_frame,
        text="Enter IP Address:",
        font=("Arial", 10),
        bg='#f0f0f0'
    )
    ip_input_label.pack(anchor=tk.W, padx=10)

    self.ip_to_url_entry = tk.Entry(
        ip_to_url_frame,
        font=("Arial", 11),
        relief=tk.SOLID,
        borderwidth=1
    )
    self.ip_to_url_entry.pack(fill=tk.X, padx=10, pady=5)
    self.ip_to_url_entry.bind('<Return>', lambda e: self.convert_ip_to_url())

    convert_ip_btn = tk.Button(
        ip_to_url_frame,
        text="Convert to URL",
        command=self.convert_ip_to_url,
        bg='#27ae60',
        fg='white',
        font=("Arial", 11, "bold"),
        relief=tk.FLAT,
        cursor='hand2',
        padx=20,
        pady=8
    )
    convert_ip_btn.pack(fill=tk.X, padx=10, pady=5)

    self.ip_to_url_result = tk.Label(
        ip_to_url_frame,
        text="",
        font=("Arial", 10),
        bg='#f0f0f0',
        fg='#27ae60',
        wraplength=680
    )
    self.ip_to_url_result.pack(padx=10, pady=5)

    canvas.pack(side="left", fill="both", expand=True)
    scrollbar.pack(side="right", fill="y")

# QR Generator Functions
def get_error_level(self):
    """Convert error level string to segno error level"""
    level_map = {
        'L (7%)': 'L',
        'M (15%)': 'M',
        'Q (25%)': 'Q',
        'H (30%)': 'H'
    }
    return level_map.get(self.error_level.get(), 'M')

def generate_qr(self):
    """Generate QR code from input URL/text"""
    url = self.url_entry.get().strip()

    if not url:
        messagebox.showwarning("Input Required", "Please enter a URL or text to generate QR code!")
        return

    try:
        error_level = self.get_error_level()
        scale = self.scale_var.get()

        self.current_qr = segno.make(url, error=error_level)

        buffer = io.BytesIO()
        self.current_qr.save(buffer, kind='png', scale=scale, border=2)
        buffer.seek(0)

        img = Image.open(buffer)

        display_size = 400
        if img.width > display_size or img.height > display_size:
            img.thumbnail((display_size, display_size), Image.Resampling.LANCZOS)

        self.qr_image = ImageTk.PhotoImage(img)
        self.qr_label.configure(image=self.qr_image, text="")

        self.save_btn.configure(state=tk.NORMAL)

        try:
            version = self.current_qr.version
            self.status_label.configure(text=f"QR Code generated successfully! Version: {version}")
        except:
            self.status_label.configure(text="QR Code generated successfully!")

    except Exception as e:
        messagebox.showerror("Error", f"Failed to generate QR code:\n{str(e)}")

def save_qr(self):
    """Save the generated QR code to file"""
    if self.current_qr is None:
        messagebox.showwarning("No QR Code", "Please generate a QR code first!")
        return

    try:
        file_path = filedialog.asksaveasfilename(
            defaultextension=".png",
            filetypes=[
                ("PNG files", "*.png"),
                ("SVG files", "*.svg"),
                ("PDF files", "*.pdf"),
                ("EPS files", "*.eps"),
                ("All files", "*.*")
            ],
            title="Save QR Code"
        )

        if file_path:
            _, ext = os.path.splitext(file_path)
            ext = ext.lower().replace('.', '')

            if not ext:
                ext = 'png'
                file_path += '.png'

            scale = self.scale_var.get()

            if ext in ['png', 'jpg', 'jpeg']:
                self.current_qr.save(file_path, kind=ext, scale=scale, border=2)
            elif ext == 'svg':
                self.current_qr.save(file_path, kind='svg', scale=scale, border=2)
            elif ext == 'pdf':
                self.current_qr.save(file_path, kind='pdf', scale=scale, border=2)
            elif ext == 'eps':
                self.current_qr.save(file_path, kind='eps', scale=scale, border=2)
            else:
                self.current_qr.save(file_path, kind='png', scale=scale, border=2)

            self.status_label.configure(
                text=f"QR Code saved successfully to: {os.path.basename(file_path)}"
            )
            messagebox.showinfo("Success", f"QR Code saved successfully!\n\n{file_path}")

    except Exception as e:
        messagebox.showerror("Save Error", f"Failed to save QR code:\n{str(e)}")

def clear_qr(self):
    """Clear the current QR code and reset the form"""
    self.url_entry.delete(0, tk.END)
    self.current_qr = None
    self.qr_image = None
    self.qr_label.configure(image='', text="QR Code will appear here")
    self.save_btn.configure(state=tk.DISABLED)
    self.status_label.configure(text="")

# QR Reader Functions
def upload_qr_image(self):
    """Upload and decode QR code image"""
    file_path = filedialog.askopenfilename(
        title="Select QR Code Image",
        filetypes=[
            ("Image files", "*.png *.jpg *.jpeg *.bmp *.gif"),
            ("All files", "*.*")
        ]
    )

    if not file_path:
        return

    try:
        # Load and display image
        img = Image.open(file_path)
        
        # Resize for display
        display_size = 250
        img_copy = img.copy()
        img_copy.thumbnail((display_size, display_size), Image.Resampling.LANCZOS)
        
        self.reader_image = ImageTk.PhotoImage(img_copy)
        self.reader_image_label.configure(image=self.reader_image, text="")

        # Decode QR code
        decoded_objects = decode(img)

        self.reader_result_text.configure(state=tk.NORMAL)
        self.reader_result_text.delete(1.0, tk.END)

        if decoded_objects:
            for obj in decoded_objects:
                decoded_data = obj.data.decode('utf-8')
                qr_type = obj.type
                self.reader_result_text.insert(tk.END, f"Type: {qr_type}\n")
                self.reader_result_text.insert(tk.END, f"Content: {decoded_data}\n")
                
                # If it's a URL, show additional info
                if decoded_data.startswith(('http://', 'https://', 'www.')):
                    self.reader_result_text.insert(tk.END, f"\nβœ“ Valid URL detected\n")
        else:
            self.reader_result_text.insert(tk.END, "No QR code found in the image.")

        self.reader_result_text.configure(state=tk.DISABLED)

    except Exception as e:
        messagebox.showerror("Error", f"Failed to read QR code:\n{str(e)}")

def copy_decoded_content(self):
    """Copy decoded content to clipboard"""
    content = self.reader_result_text.get(1.0, tk.END).strip()
    if content and content != "No QR code found in the image.":
        self.root.clipboard_clear()
        self.root.clipboard_append(content)
        messagebox.showinfo("Copied", "Content copied to clipboard!")
    else:
        messagebox.showwarning("No Content", "No content to copy!")

# Advanced IP Tools Functions
def get_advanced_ip_location(self):
    """Get advanced IP location with multiple data sources"""
    self.ip_location_text.configure(state=tk.NORMAL)
    self.ip_location_text.delete(1.0, tk.END)
    self.ip_location_text.insert(tk.END, "πŸ”„ Fetching precise geolocation data...\n")
    self.root.update()

    # Try multiple APIs for best accuracy
    apis = [
        self.try_ipapi_co,
        self.try_ip_api_com,
        self.try_ipinfo_io,
    ]

    for api_func in apis:
        try:
            data = api_func()
            if data:
                self.location_data = data
                self.display_location_data(data)
                
                # Enable map buttons
                self.open_google_maps_btn.configure(state=tk.NORMAL)
                self.open_osm_btn.configure(state=tk.NORMAL)
                self.additional_info_btn.configure(state=tk.NORMAL)
                return
        except Exception as e:
            continue

    # If all APIs fail
    self.ip_location_text.delete(1.0, tk.END)
    self.ip_location_text.insert(tk.END, "❌ Unable to fetch location data.\n")
    self.ip_location_text.insert(tk.END, "Please check your internet connection.")
    self.ip_location_text.configure(state=tk.DISABLED)

def display_location_data(self, data):
    """Display formatted location data"""
    self.ip_location_text.delete(1.0, tk.END)
    
    info = f"""╔══════════════════════════════════════════╗

β•‘ NETWORK & LOCATION INFO β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

🌐 IP ADDRESS
{data.get('ip', 'N/A')}

πŸ“ PRECISE LOCATION
City: {data.get('city', 'N/A')}
Region: {data.get('region', 'N/A')}
Country: {data.get('country_name', 'N/A')} ({data.get('country_code', 'N/A')})
Postal: {data.get('postal', 'N/A')}

πŸ—ΊοΈ GPS COORDINATES
Latitude: {data.get('latitude', 'N/A')}
Longitude: {data.get('longitude', 'N/A')}
Accuracy: ~{data.get('accuracy', '100-1000')}m radius

🏒 ISP & NETWORK
Provider: {data.get('isp', 'N/A')}
Organization: {data.get('org', 'N/A')}
ASN: {data.get('asn', 'N/A')}

⏰ TIMEZONE
Timezone: {data.get('timezone', 'N/A')}
UTC Offset: {data.get('utc_offset', 'N/A')}

🌍 ADDITIONAL INFO
Continent: {data.get('continent', 'N/A')}
Currency: {data.get('currency', 'N/A')}
Languages: {data.get('languages', 'N/A')}

"""
self.ip_location_text.insert(tk.END, info)
self.ip_location_text.configure(state=tk.DISABLED)

def try_ipapi_co(self):
    """Try ipapi.co API - Most comprehensive"""
    response = requests.get('https://ipapi.co/json/', timeout=10)
    if response.status_code == 200:
        data = response.json()
        return {
            'ip': data.get('ip'),
            'city': data.get('city'),
            'region': data.get('region'),
            'country_name': data.get('country_name'),
            'country_code': data.get('country_code'),
            'postal': data.get('postal'),
            'latitude': data.get('latitude'),
            'longitude': data.get('longitude'),
            'timezone': data.get('timezone'),
            'utc_offset': data.get('utc_offset'),
            'isp': data.get('org'),
            'org': data.get('org'),
            'asn': data.get('asn'),
            'continent': data.get('continent_code'),
            'currency': data.get('currency'),
            'languages': data.get('languages'),
            'accuracy': '100-500'
        }
    return None

def try_ip_api_com(self):
    """Try ip-api.com API"""
    response = requests.get('http://ip-api.com/json/?fields=66846719', timeout=10)
    if response.status_code == 200:
        data = response.json()
        if data.get('status') == 'success':
            return {
                'ip': data.get('query'),
                'city': data.get('city'),
                'region': data.get('regionName'),
                'country_name': data.get('country'),
                'country_code': data.get('countryCode'),
                'postal': data.get('zip'),
                'latitude': data.get('lat'),
                'longitude': data.get('lon'),
                'timezone': data.get('timezone'),
                'utc_offset': data.get('offset'),
                'isp': data.get('isp'),
                'org': data.get('org'),
                'asn': data.get('as'),
                'continent': data.get('continent'),
                'currency': data.get('currency'),
                'languages': 'N/A',
                'accuracy': '500-1000'
            }
    return None

def try_ipinfo_io(self):
    """Try ipinfo.io API"""
    response = requests.get('https://ipinfo.io/json', timeout=10)
    if response.status_code == 200:
        data = response.json()
        loc = data.get('loc', ',').split(',')
        return {
            'ip': data.get('ip'),
            'city': data.get('city'),
            'region': data.get('region'),
            'country_name': data.get('country'),
            'country_code': data.get('country'),
            'postal': data.get('postal'),
            'latitude': loc[0] if len(loc) > 0 else 'N/A',
            'longitude': loc[1] if len(loc) > 1 else 'N/A',
            'timezone': data.get('timezone'),
            'utc_offset': 'N/A',
            'isp': data.get('org'),
            'org': data.get('org'),
            'asn': 'N/A',
            'continent': 'N/A',
            'currency': 'N/A',
            'languages': 'N/A',
            'accuracy': '1000-5000'
        }
    return None

def open_in_maps(self, map_type):
    """Open location in map service"""
    if not self.location_data:
        messagebox.showwarning("No Location", "Please get location data first!")
        return

    lat = self.location_data.get('latitude')
    lon = self.location_data.get('longitude')

    if not lat or not lon or lat == 'N/A' or lon == 'N/A':
        messagebox.showwarning("No Coordinates", "GPS coordinates not available!")
        return

    try:
        if map_type == 'google':
            # Open in Google Maps
            url = f"https://www.google.com/maps?q={lat},{lon}&z=15"
            webbrowser.open(url)
        elif map_type == 'osm':
            # Open in OpenStreetMap
            url = f"https://www.openstreetmap.org/?mlat={lat}&mlon={lon}&zoom=15"
            webbrowser.open(url)
    except Exception as e:
        messagebox.showerror("Error", f"Failed to open map:\n{str(e)}")

def get_additional_network_info(self):
    """Get additional network and routing information"""
    if not self.location_data:
        messagebox.showwarning("No Data", "Please get location data first!")
        return

    ip = self.location_data.get('ip')
    if not ip or ip == 'N/A':
        messagebox.showwarning("No IP", "IP address not available!")
        return

    try:
        # Get additional info
        info_window = tk.Toplevel(self.root)
        info_window.title("Additional Network Information")
        info_window.geometry("600x500")
        info_window.configure(bg='#f0f0f0')

        title_label = tk.Label(
            info_window,
            text="πŸ” Advanced Network Analysis",
            font=("Arial", 14, "bold"),
            bg='#2c3e50',
            fg='white',
            pady=15
        )
        title_label.pack(fill=tk.X)

        info_text = tk.Text(
            info_window,
            font=("Courier", 9),
            wrap=tk.WORD,
            relief=tk.SOLID,
            borderwidth=1
        )
        info_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        info_text.insert(tk.END, f"Analyzing IP: {ip}\n")
        info_text.insert(tk.END, "=" * 60 + "\n\n")

        # DNS Information
        try:
            hostname = socket.gethostbyaddr(ip)[0]
            info_text.insert(tk.END, f"πŸ”Ή Reverse DNS:\n   {hostname}\n\n")
        except:
            info_text.insert(tk.END, f"πŸ”Ή Reverse DNS:\n   No hostname found\n\n")

        # Try to get more info from ipapi.co
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=10)
            if response.status_code == 200:
                data = response.json()
                
                info_text.insert(tk.END, "πŸ”Ή Network Details:\n")
                info_text.insert(tk.END, f"   ASN: {data.get('asn', 'N/A')}\n")
                info_text.insert(tk.END, f"   Network: {data.get('network', 'N/A')}\n")
                info_text.insert(tk.END, f"   Version: IPv{data.get('version', 'N/A')}\n\n")
                
                info_text.insert(tk.END, "πŸ”Ή Geographic Details:\n")
                info_text.insert(tk.END, f"   Capital: {data.get('country_capital', 'N/A')}\n")
                info_text.insert(tk.END, f"   Area: {data.get('country_area', 'N/A')} kmΒ²\n")
                info_text.insert(tk.END, f"   Population: {data.get('country_population', 'N/A')}\n")
                info_text.insert(tk.END, f"   Calling Code: +{data.get('country_calling_code', 'N/A')}\n\n")
                
                info_text.insert(tk.END, "πŸ”Ή Connection Type:\n")
                info_text.insert(tk.END, f"   Type: {data.get('connection_type', 'N/A')}\n\n")
                
                if data.get('threat'):
                    threat_data = data.get('threat', {})
                    info_text.insert(tk.END, "πŸ”Ή Security Information:\n")
                    info_text.insert(tk.END, f"   Tor Exit: {threat_data.get('is_tor', False)}\n")
                    info_text.insert(tk.END, f"   Proxy: {threat_data.get('is_proxy', False)}\n")
                    info_text.insert(tk.END, f"   Anonymous: {threat_data.get('is_anonymous', False)}\n\n")
        except:
            info_text.insert(tk.END, "Additional details unavailable\n")

        info_text.configure(state=tk.DISABLED)

        close_btn = tk.Button(
            info_window,
            text="Close",
            command=info_window.destroy,
            bg='#e74c3c',
            fg='white',
            font=("Arial", 11, "bold"),
            relief=tk.FLAT,
            cursor='hand2',
            pady=10
        )
        close_btn.pack(fill=tk.X, padx=10, pady=(0, 10))

    except Exception as e:
        messagebox.showerror("Error", f"Failed to get additional info:\n{str(e)}")

def convert_url_to_ip(self):
    """Convert URL/domain to IP address with additional info"""
    url = self.url_to_ip_entry.get().strip()
    
    if not url:
        messagebox.showwarning("Input Required", "Please enter a URL or domain!")
        return

    try:
        # Remove protocol if present
        domain = url.replace('https://', '').replace('http://', '').split('/')[0]
        
        # Get IP address
        ip_address = socket.gethostbyname(domain)
        
        # Try to get geolocation for this IP
        try:
            response = requests.get(f'https://ipapi.co/{ip_address}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                location_info = f"\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}"
                org_info = f"\n🏒 Organization: {data.get('org', 'N/A')}"
            else:
                location_info = ""
                org_info = ""
        except:
            location_info = ""
            org_info = ""
        
        self.url_to_ip_result.configure(
            text=f"βœ“ Domain: {domain}\nβœ“ IP Address: {ip_address}{location_info}{org_info}",
            fg='#27ae60'
        )

    except socket.gaierror:
        self.url_to_ip_result.configure(
            text=f"βœ— Could not resolve domain: {domain}\n(Check spelling or DNS availability)",
            fg='#e74c3c'
        )
    except Exception as e:
        self.url_to_ip_result.configure(
            text=f"βœ— Error: {str(e)}",
            fg='#e74c3c'
        )

def convert_ip_to_url(self):
    """Convert IP address to URL using reverse DNS with geolocation"""
    ip = self.ip_to_url_entry.get().strip()
    
    if not ip:
        messagebox.showwarning("Input Required", "Please enter an IP address!")
        return

    try:
        # Reverse DNS lookup
        hostname = socket.gethostbyaddr(ip)[0]
        
        # Try to get location info
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                location_info = f"\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}"
                org_info = f"\n🏒 Organization: {data.get('org', 'N/A')}"
            else:
                location_info = ""
                org_info = ""
        except:
            location_info = ""
            org_info = ""
        
        self.ip_to_url_result.configure(
            text=f"βœ“ IP: {ip}\nβœ“ Hostname: {hostname}{location_info}{org_info}",
            fg='#27ae60'
        )

    except socket.herror:
        # Even if no hostname, try to show location
        try:
            response = requests.get(f'https://ipapi.co/{ip}/json/', timeout=5)
            if response.status_code == 200:
                data = response.json()
                self.ip_to_url_result.configure(
                    text=f"βœ“ IP: {ip}\n⚠️ No hostname found\nπŸ“ Location: {data.get('city', 'N/A')}, {data.get('country_name', 'N/A')}\n🏒 Organization: {data.get('org', 'N/A')}",
                    fg='#f39c12'
                )
            else:
                self.ip_to_url_result.configure(
                    text=f"βœ— No hostname found for IP: {ip}",
                    fg='#e74c3c'
                )
        except:
            self.ip_to_url_result.configure(
                text=f"βœ— No hostname found for IP: {ip}",
                fg='#e74c3c'
            )
    except Exception as e:
        self.ip_to_url_result.configure(
            text=f"βœ— Error: {str(e)}",
            fg='#e74c3c'
        )

def main():
"""Main function to run the application"""
root = tk.Tk()
app = QRCodeGenerator(root)
root.mainloop()

if name == "main":
main()

choaslord2010 changed pull request status to closed
choaslord2010 changed pull request status to open
Ready to merge
This branch is ready to get merged automatically.

Sign up or log in to comment