欢迎光临UUpython
最大、最新、最全的Python代码收集站

[GUI]阿里云DDNS更新器

这段代码实现了一个用于自动更新阿里云 DNS 记录的 GUI 程序。用户可以输入阿里云的 Access Key ID、Access Key Secret、域名和子域名,然后点击按钮来检查当前的公网 IP 地址,与 DNS 记录中的 IP 地址进行比较,如果不一致,则自动更新 DNS 记录。

以下是代码的主要部分:

  1. config.ini 配置文件中读取默认的 Access Key ID、Access Key Secret、域名和子域名。
  2. 创建一个 tkinter 主窗口,并设置窗口大小和标题。
  3. 创建输入框和标签,用于输入 Access Key ID、Access Key Secret、域名和子域名。如果配置文件中存在默认值,则会预填充输入框。
  4. 创建一个滚动文本框,用于显示输出信息。
  5. get_current_ip 函数:通过向 ipinfo.io 发送请求,获取当前主机的公网 IP 地址。
  6. compute_signature 函数:根据给定的参数和 Access Key Secret 计算签名。
  7. send_request 函数:构造请求参数,发送请求并返回响应结果。
  8. get_record_value 函数:获取当前子域名的 DNS 记录值和记录 ID。
  9. update_dns 函数:更新 DNS 记录。
  10. start_process 函数:开始更新 DNS 记录的流程。获取当前 IP 地址,与 DNS 记录中的 IP 进行比较,如果不一致,则更新 DNS 记录。
  11. 创建一个更新按钮,当点击按钮时会调用 start_process 函数。
  12. 启动 tkinter 主循环。

请注意,这是一个用于阿里云 DNS 记录更新的示例代码,其中可能会缺少某些错误处理和细节。为了确保程序的稳定性和安全性,你可能需要添加适当的错误处理和用户交互提示。同时,确保在使用敏感信息(如 Access Key 和 Access Key Secret)时,注意安全性。

import configparser
import sys
import requests
import urllib.parse
import hmac
import base64
import hashlib
import time
import uuid
from datetime import datetime
import tkinter as tk
from tkinter import scrolledtext
 
# 尝试从配置文件中读取配置
config = configparser.ConfigParser()
config.read('config.ini')
 
try:
    access_key_id_default = config.get('aliyun', 'access_key_id')
    access_key_secret_default = config.get('aliyun', 'access_key_secret')
    domain_default = config.get('aliyun', 'domain')
    subdomain_default = config.get('aliyun', 'subdomain')
except:
    access_key_id_default = ""
    access_key_secret_default = ""
    domain_default = ""
    subdomain_default = ""
 
# 创建主窗口并设置窗口大小和标题
root = tk.Tk()
root.geometry('400x350')
root.title('阿里云DDNS')
 
# 创建输入框和对应的标签,如果配置文件存在,则预填充输入框
access_key_id_label = tk.Label(root, text="Access Key ID:")
access_key_id_label.pack()
access_key_id_entry = tk.Entry(root, width=50)
access_key_id_entry.insert(0, access_key_id_default)
access_key_id_entry.pack()
 
access_key_secret_label = tk.Label(root, text="Access Key Secret:")
access_key_secret_label.pack()
access_key_secret_entry = tk.Entry(root, width=50)
access_key_secret_entry.insert(0, access_key_secret_default)
access_key_secret_entry.pack()
 
domain_label = tk.Label(root, text="Domain:")
domain_label.pack()
domain_entry = tk.Entry(root, width=50)
domain_entry.insert(0, domain_default)
domain_entry.pack()
 
subdomain_label = tk.Label(root, text="Subdomain:")
subdomain_label.pack()
subdomain_entry = tk.Entry(root, width=50)
subdomain_entry.insert(0, subdomain_default)
subdomain_entry.pack()
 
# 创建一个滚动文本框来显示输出
output_text = scrolledtext.ScrolledText(root, height=10, width=50)
output_text.pack()
 
# 获取当前主机的公网IP
def get_current_ip():
    try:
        response = requests.get('http://ipinfo.io/json')
        return response.json()['ip']
    except Exception as e:
        output_text.insert(tk.END, f'获取当前IP失败: {str(e)}\n')
        return None
 
# 生成签名
def compute_signature(access_key_secret, parameters):
    sorted_parameters = sorted(parameters.items(), key=lambda item:item[0])
    canonicalized_query_string = urllib.parse.urlencode(sorted_parameters)
    string_to_sign = 'GET&%2F&' + urllib.parse.quote(canonicalized_query_string, safe='~')
    h = hmac.new((access_key_secret + "&").encode('utf-8'), string_to_sign.encode('utf-8'), hashlib.sha1)
    signature = base64.encodebytes(h.digest()).strip()
    return signature.decode('utf-8')
 
# 发送请求
def send_request(parameters):
    common_parameters = {
        'Format': 'JSON',
        'Version': '2015-01-09',
        'AccessKeyId': access_key_id_entry.get(),
        'SignatureMethod': 'HMAC-SHA1',
        'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        'SignatureVersion': '1.0',
        'SignatureNonce': str(uuid.uuid1()),
    }
    parameters.update(common_parameters)
    parameters['Signature'] = compute_signature(access_key_secret_entry.get(), parameters)
    url = 'https://alidns.aliyuncs.com/?' + urllib.parse.urlencode(parameters)
    try:
        response = requests.get(url)
        return response.json()
    except Exception as e:
        output_text.insert(tk.END, f'发送请求失败: {str(e)}\n')
        return None
 
# 获取DNS记录的当前值
def get_record_value():
    parameters = {
        'Action': 'DescribeSubDomainRecords',
        'SubDomain': f"{subdomain_entry.get()}.{domain_entry.get()}",
    }
    records = send_request(parameters)
    if records and records['TotalCount'] != 0:
        for record in records['DomainRecords']['Record']:
            if record['Type'] == 'A':  # 检查记录类型是否为'A'
                output_text.insert(tk.END, f"找到A记录,RecordId:{record['RecordId']},值:{record['Value']}\n")
                return record['Value'], record['RecordId']
    return None, None
 
# 更新DNS记录
def update_dns(record_id, ip):
    parameters = {
        'Action': 'UpdateDomainRecord',
        'RecordId': record_id,
        'RR': subdomain_entry.get(),
        'Type': 'A',
        'Value': ip,
    }
    response = send_request(parameters)
    if response:
        output_text.insert(tk.END, f'DNS记录已更新为 {ip}\n')
    return response
 
# 创建一个按钮,当点击这个按钮时会调用 update_dns_records 函数
def start_process():
    current_ip = get_current_ip()
    if current_ip:
        output_text.insert(tk.END, f'当前IP为 {current_ip}\n')
        record_value, record_id = get_record_value()
 
        if record_value is None or record_id is None:  
            output_text.insert(tk.END, '未找到当前DNS记录\n')
        else:
            output_text.insert(tk.END, f'当前DNS记录为 {record_value}\n')
            if record_value != current_ip:
                response = update_dns(record_id, current_ip)
                if response and response.get('RecordId') == record_id:  
                    output_text.insert(tk.END, 'DNS记录更新成功\n')
            else:
                output_text.insert(tk.END, '无需更新DNS记录\n')
 
update_button = tk.Button(root, text="更新DNS记录", command=start_process)
update_button.pack()
 
# 启动主循环
root.mainloop()
赞(0) 打赏
未经允许不得转载:UUpython » [GUI]阿里云DDNS更新器
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!