Spaces:
Sleeping
Sleeping
File size: 5,230 Bytes
0763242 2975274 0763242 2975274 0763242 2975274 0763242 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import os
import io
import base64
import subprocess
import re
import platform
from flask import Flask, render_template, request, jsonify, send_file
import segno
from segno import helpers
from PIL import Image
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max upload
def get_current_wifi_ssid():
"""
Attempt to get the current connected WiFi SSID.
Works primarily on macOS for local development.
Returns None if detection fails or running in cloud.
"""
try:
system = platform.system()
if system == 'Darwin': # macOS
process = subprocess.Popen(
['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '-I'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
out, err = process.communicate()
if process.returncode == 0:
output = out.decode('utf-8')
match = re.search(r' SSID: (.+)', output)
if match:
return match.group(1).strip()
elif system == 'Linux':
# Basic attempt for Linux (might work if nmcli is installed and has permissions)
# Unlikely to work in Docker/HF Spaces without host networking
pass
except Exception as e:
print(f"WiFi detection failed: {e}")
return None
def hex_to_rgb(hex_color):
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
@app.route('/')
def index():
default_ssid = get_current_wifi_ssid() or ''
return render_template('index.html', default_ssid=default_ssid)
@app.route('/api/generate', methods=['POST'])
def generate_qr():
try:
data = request.form
qr_type = data.get('type', 'text')
content = data.get('content', '')
fg_color = data.get('fg_color', '#000000')
bg_color = data.get('bg_color', '#ffffff')
scale = int(data.get('scale', 10))
border = int(data.get('border', 4))
# Handle colors (Segno expects hex or RGB tuple, but let's be safe)
# Segno handles hex strings well.
qr = None
# 1. Generate QR Object
if qr_type == 'wifi':
ssid = data.get('wifi_ssid')
password = data.get('wifi_password')
security = data.get('wifi_security', 'WPA')
hidden = data.get('wifi_hidden') == 'true'
qr = helpers.make_wifi(ssid=ssid, password=password, security=security, hidden=hidden)
elif qr_type == 'vcard':
name = data.get('vcard_name')
displayname = data.get('vcard_displayname')
email = data.get('vcard_email')
phone = data.get('vcard_phone')
url = data.get('vcard_url')
# Segno make_vcard is powerful
qr = helpers.make_vcard(name=name, displayname=displayname, email=email, phone=phone, url=url)
else:
# Default text/url
if not content:
return jsonify({'error': '内容不能为空'}), 400
qr = segno.make(content, error='h') # High error correction for logos
# 2. Convert to PIL Image
out = io.BytesIO()
qr.save(out, kind='png', scale=scale, border=border, dark=fg_color, light=bg_color)
out.seek(0)
img = Image.open(out).convert("RGBA")
# 3. Handle Logo
logo_file = request.files.get('logo')
if logo_file:
logo = Image.open(logo_file).convert("RGBA")
# Calculate logo size (e.g., 20% of QR width)
qr_width, qr_height = img.size
logo_max_size = int(qr_width * 0.25) # 25% coverage max
# Resize logo maintaining aspect ratio
logo.thumbnail((logo_max_size, logo_max_size), Image.Resampling.LANCZOS)
# Position centered
logo_pos = ((qr_width - logo.size[0]) // 2, (qr_height - logo.size[1]) // 2)
# Paste logo (with transparency support)
# Create a white background for logo if needed or just paste
# Usually better to have a small white border around logo for readability
# Let's create a white backing for the logo
logo_bg_size = (logo.size[0] + 4, logo.size[1] + 4) # 4px padding
logo_bg = Image.new('RGBA', logo_bg_size, bg_color)
logo_bg_pos = (logo_pos[0] - 2, logo_pos[1] - 2)
img.paste(logo_bg, logo_bg_pos, logo_bg) # Paste white square
img.paste(logo, logo_pos, logo) # Paste logo
# 4. Return as Base64
final_out = io.BytesIO()
img.save(final_out, format='PNG')
final_out.seek(0)
b64_data = base64.b64encode(final_out.getvalue()).decode()
return jsonify({
'image': f'data:image/png;base64,{b64_data}',
'filename': 'qrcode.png'
})
except Exception as e:
print(f"Error: {e}")
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)
|