Skip to content

Commit

Permalink
feat(config): cli argument supports to set config
Browse files Browse the repository at this point in the history
  • Loading branch information
NewFuture authored Jun 14, 2021
1 parent cd4c7de commit 91a82eb
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 56 deletions.
63 changes: 7 additions & 56 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
@modified: rufengsuixing
"""
from __future__ import print_function
from argparse import ArgumentParser, RawTextHelpFormatter
from json import load as loadjson, dump as dumpjson
from time import ctime
from os import path, environ, stat, name as os_name
from os import path, environ, name as os_name
from tempfile import gettempdir
from logging import DEBUG, basicConfig, info, warning, error, debug
from subprocess import check_output
Expand All @@ -18,6 +16,7 @@

from util import ip
from util.cache import Cache
from util.config import init_config, get_config

__version__ = "${BUILD_SOURCEBRANCHNAME}@${BUILD_DATE}" # CI 时会被Tag替换
__description__ = "automatically update DNS records to dynamic local IP [自动更新DNS记录指向本地IP]"
Expand All @@ -38,48 +37,6 @@
CACHE_FILE = path.join(gettempdir(), 'ddns.cache')


def get_config(key=None, default=None, path="config.json"):
"""
读取配置
"""
if not hasattr(get_config, "config"):
try:
with open(path) as configfile:
get_config.config = loadjson(configfile)
get_config.time = stat(path).st_mtime
except IOError:
error(' Config file `%s` does not exist!' % path)
with open(path, 'w') as configfile:
configure = {
"$schema": "https://ddns.newfuture.cc/schema/v2.8.json",
"id": "YOUR ID or EMAIL for DNS Provider",
"token": "YOUR TOKEN or KEY for DNS Provider",
"dns": "dnspod",
"ipv4": [
"newfuture.cc",
"ddns.newfuture.cc"
],
"ipv6": [
"newfuture.cc",
"ipv6.ddns.newfuture.cc"
],
"index4": "default",
"index6": "default",
"ttl": None,
"proxy": None,
"debug": False,
}
dumpjson(configure, configfile, indent=2, sort_keys=True)
sys.stdout.write("New template configure file `%s` is generated.\n" % path)
sys.exit(1)
except:
sys.exit('fail to load config from file: %s' % path)
if key:
return get_config.config.get(key, default)
else:
return get_config.config


def get_ip(ip_type, index="default"):
"""
get IP address
Expand Down Expand Up @@ -138,7 +95,7 @@ def update_ip(ip_type, cache, dns, proxy_list):
index_rule = get_config('index' + ip_type, "default") # 从配置中获取index配置
address = get_ip(ip_type, index_rule)
if not address:
error('Fail to get %s address!' ,ipname)
error('Fail to get %s address!', ipname)
return False
elif cache and (address == cache[ipname]):
print('.', end=" ") # 缓存命中
Expand All @@ -157,14 +114,7 @@ def main():
"""
更新
"""
parser = ArgumentParser(description=__description__,
epilog=__doc__, formatter_class=RawTextHelpFormatter)
parser.add_argument('-v', '--version',
action='version', version=__version__)
parser.add_argument('-c', '--config',
default="config.json", help="run with config file [配置文件路径]")
config_file = parser.parse_args().config
get_config(path=config_file)
init_config(__description__, __doc__, __version__)
# Dynamicly import the dns module as configuration
dns_provider = str(get_config('dns', 'dnspod').lower())
dns = getattr(__import__('dns', fromlist=[dns_provider]), dns_provider)
Expand All @@ -177,7 +127,8 @@ def main():
level=DEBUG,
format='%(asctime)s <%(module)s.%(funcName)s> %(lineno)d@%(pathname)s \n[%(levelname)s] %(message)s')
print("DDNS[", __version__, "] run:", os_name, sys.platform)
print("Configuration was loaded from <==", path.abspath(config_file))
print("Configuration was loaded from <==",
path.abspath(get_config("config")))
print("=" * 25, ctime(), "=" * 25, sep=' ')

proxy = get_config('proxy') or 'DIRECT'
Expand All @@ -186,7 +137,7 @@ def main():
cache = get_config('cache', True) and Cache(CACHE_FILE)
if cache is False:
info("Cache is disabled!")
elif get_config.time >= cache.time:
elif get_config("config_modified_time") is None or get_config("config_modified_time") >= cache.time:
warning("Cache file is out of dated.")
cache.clear()
elif not cache:
Expand Down
113 changes: 113 additions & 0 deletions util/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from argparse import ArgumentParser, ArgumentTypeError, Namespace, RawTextHelpFormatter
from json import load as loadjson, dump as dumpjson
from logging import error
from os import stat
from time import time

import sys

__cli_args = {} # type: Namespace
__config = {} # type: dict


def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise ArgumentTypeError('Boolean value expected.')


def init_config(description, doc, version):
global __cli_args
"""
配置
"""
parser = ArgumentParser(description=description,
epilog=doc, formatter_class=RawTextHelpFormatter)
parser.add_argument('-v', '--version',
action='version', version=version)
parser.add_argument('-c', '--config', help="run with config file [配置文件路径]")

# 参数定义
parser.add_argument('--dns', help="DNS Provider [DNS服务提供商]", choices=[
'alidns', 'cloudflare', 'dnscom', 'dnspod', 'dnspod_com', 'he', 'huaweidns', 'callback'])
parser.add_argument('--id', help="api ID [授权账户]")
parser.add_argument('--token', help="api token or Secret key [授权访问凭证或密钥]")
parser.add_argument('--ipv4', nargs="*",
help="ipv4 domain list [IPV4域名列表]")
parser.add_argument('--ipv6', nargs="*",
help="ipv6 domain list [IPV6域名列表]")
parser.add_argument('--index4', help="the way to get ipv4 [IPV4 获取方式]")
parser.add_argument('--index6', help="the way to get ipv6 [IPV6获取方式]")
parser.add_argument('--ttl', type=int, help="ttl for DNS [DNS 解析 TTL 时间]")
parser.add_argument('--proxy', nargs="*",
help="https proxy [设置http 代理,多代理逐个尝试直到成功]")
parser.add_argument('--debug', type=str2bool, nargs='?',
const=True, help="debug mode [是否开启调试,默认否]", )
parser.add_argument('--cache', type=str2bool, nargs='?',
const=True, help="eusing cache [是否缓存记录,默认是]")

__cli_args = parser.parse_args()
has_cli_config = __cli_args.token or __cli_args.id
__load_config(__cli_args.config or "config.json", has_cli_config)
if __cli_args.config is None:
__cli_args.config = "config.json"


def __load_config(path="config.json", skip_auto_generation=False):
"""
加载配置
"""
global __config, config_modified_time
try:
with open(path) as configfile:
__config = loadjson(configfile)
__config["config_modified_time"] = stat(path).st_mtime
except IOError:
if skip_auto_generation:
__config["config_modified_time"] = time()
return
error(' Config file `%s` does not exist!' % path)
with open(path, 'w') as configfile:
configure = {
"$schema": "https://ddns.newfuture.cc/schema/v2.8.json",
"id": "YOUR ID or EMAIL for DNS Provider",
"token": "YOUR TOKEN or KEY for DNS Provider",
"dns": "dnspod",
"ipv4": [
"newfuture.cc",
"ddns.newfuture.cc"
],
"ipv6": [
"newfuture.cc",
"ipv6.ddns.newfuture.cc"
],
"index4": "default",
"index6": "default",
"ttl": None,
"proxy": None,
"debug": False,
}
dumpjson(configure, configfile, indent=2, sort_keys=True)
sys.stdout.write(
"New template configure file `%s` is generated.\n" % path)
sys.exit(1)
except:
sys.exit('fail to load config from file: %s' % path)


def get_config(key, default=None):
"""
读取配置
"""
if hasattr(__cli_args, key) and getattr(__cli_args, key) is not None:
return getattr(__cli_args, key)
if key in __config:
return __config.get(key)
return default

0 comments on commit 91a82eb

Please sign in to comment.