Browse Source

Merge branch 'release/v1.2.1'

liuyuqi-dellpc 8 months ago
parent
commit
688de4ccf8

+ 65 - 0
.github/workflows/build.yml

@@ -0,0 +1,65 @@
+name: Publish Installers
+
+on:
+  workflow_dispatch: ~
+  push:
+    branches: [master]
+    tags: [v*]
+
+jobs:
+  build:
+    name: Build ${{ matrix.os }} Package
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix: 
+        os: [ubuntu-20.04]
+
+    steps:
+      - name: Checkout Code
+        uses: actions/checkout@v4
+
+      - name: Set Release Version
+        id: get_version
+        shell: bash
+        run: |
+          echo "::set-output name=hash::$(git rev-parse --short HEAD)"
+          echo "::set-output name=date::$(date +%Y%m%d)"
+          echo "::set-output name=url::$(git remote get-url origin)"
+          
+      - name: Set Up Python
+        uses: actions/setup-python@v4
+        with:
+          python-version: '3.12'
+          cache: pip
+          cache-dependency-path: '**/requirements*.txt'
+
+      - name: Install Dependencies
+        run: |
+          python -m pip install --upgrade pip wheel setuptools
+          pip install -r requirements.txt
+          python -m pip install pyinstaller
+
+      - name: Build Package
+        run: |
+          python -m PyInstaller -F -c  --name search_domain main.py
+
+      - name: Update to ali oss
+        uses: yizhoumo/setup-ossutil@v1
+        with:
+          endpoint: oss-cn-qingdao.aliyuncs.com
+          access-key-id: ${{ secrets.OSS_KEY_ID }}
+          access-key-secret: ${{ secrets.OSS_KEY_SECRET }}
+          
+      - name: cp files to aliyun
+        run: |
+          ossutil cp -r dist/ oss://yoqi-software/develop/search_domain/${{ steps.get_version.outputs.date }}-${{ steps.get_version.outputs.hash }}/
+      
+      - uses: leafney/dingtalk-action@v1
+        if: always()
+        env:
+          DINGTALK_ACCESS_TOKEN: ${{ secrets.DINGTALK_ACCESS_TOKEN }}
+        with:
+          msgtype: link
+          title: 'search_domain build success'
+          text: 'please download from aliyun oss. [git.yoqi.me]'
+          msg_url: '${{ steps.get_version.outputs.url }}'

+ 2 - 0
README.md

@@ -2,6 +2,8 @@
 
 域名批量检索可用 重构了Java项目:[SearchDomain](https://git.yoqi.me/lyq/SearchDomain)
 
+
+
 ## Develop
 
 

+ 11 - 7
README.zh-CN.md

@@ -6,18 +6,20 @@
 
 
 ```
-virtualvenv .venv
+virtualenv .venv
+source ./.venv/bin/activate
 pip install -r requirements.txt
 ```
 
 1、批量生成域名
 ```
-python generateDomain.py
+python main.py generate
+python main.py generate_en
 ```
 
 2、批量检测域名是否可以注册,并将结果保存到数据库或文件
 ```
-python main.py
+python main.py search
 ```
 
 
@@ -36,13 +38,15 @@ docker run -it --rm -v /data/searchdomain:/app ccr.ccs.tencentyun.com/jianboy/se
 ```
 useradd -u 5678 searchdomain
 
-docker pull ccr.ccs.tencentyun.com/jianboy/searchdomain:v1.0.5
-
-docker run -it --rm -v /data/searchdomain:/app ccr.ccs.tencentyun.com/jianboy/searchdomain:v1.0.5
-
 alias searchdomain='docker run -it --rm -v /data:/app jianboy/searchdomain'
 
 searchdomain --input domain.txt --output result.txt
 
 ```
 
+打包:
+```
+mkdir -p dist
+cp domain.txt.txt dist/
+pyinstaller  -F -c  --name search_domain  main.py
+```

+ 36 - 0
console.py

@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+"""
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2024/04/26
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   windows console mode
+
+"""
+import argparse
+import os
+import sys
+from searchdomain import SearchDomain
+
+print('''
+      Search Domain 域名搜索工具 v1.0
+      author: liuyuqi
+      email: liuyuqi.gov@msn.cn
+      ''')
+
+comnand = input('''
+        1. 域名批量生成
+        2. 域名批量查询(查询是否可以注册)
+        3. 退出
+        请选择操作: 
+        ''')
+
+if comnand == '1':
+    domain = input('请输入域名: ')
+    search = SearchDomain(domain)
+    search.run()
+elif comnand == '2':
+    sys.exit(0)
+
+if __name__=='__main__':
+    pass

+ 34 - 0
docs/README.md

@@ -0,0 +1,34 @@
+# Search Domain Docs
+
+本项目实现了批量生成域名,批量检索可用域名的功能,检索域名可用性飞速。
+
+## 原理介绍
+
+### 批量生成域名
+
+根据数据(拼音,英文)等双拼组合,数据文件夹: data/a.csv, b.csv 。执行如下命令:
+
+```
+searchdomain generate --lang zh --keyword gpt,go --position prefix --domain io,com,cn
+
+```
+
+--lang zh 表示拼音组合,en表示英语单词组合
+--keyword gpt,go 表示关键词,和双拼词库组合
+--position prefix 表示生成的双拼在前还是在后
+--domain io,com,cn 表示域名后缀
+
+
+
+### 批量检索域名
+
+基于 whois 方法高效验证域名的可用性,相较于通过其他网站的API方法速度快上10倍,配合多线程能够实现百倍加速检索。
+
+由于 DNS 服务器的安全限制,请求过多过快会拒绝返回。只需要休息一会就可以了。
+
+```
+searchdomain search --input domain.txt --output result.txt
+```
+先生成域名,然后依据 domain.txt 域名列表,进行批量检索是否域名可用。
+
+

+ 21 - 12
main.py

@@ -6,20 +6,29 @@
 @Time    :   2023/03/08 17:39:34
 @License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
 @Desc    :   enter point
+searchdomain generate --lang zh --keyword gpt,go --position prefix --domain io,com,cn
+searchdomain search --
 '''
 
 from searchdomain import SearchDomain, GenerateDomain, GenerateEnDomain
+from searchdomain.options import parse_args
+import sys
 
 if __name__== "__main__":
-    # 生成域名    
-    # generateDomain = GenerateDomain() 
-    # generateDomain.run()
-
-    # generateDomain = GenerateEnDomain() 
-    # generateDomain.run()
-
-    # 查询域名可用
-    serachdomain = SearchDomain(debug=True, export_all=False) 
-    serachdomain.run()
-
-    
+    args = parse_args()
+    if args.get("command","")=="generate":
+        if args.get("lang","en")=="en":
+            generateDomain = GenerateEnDomain(params=args) 
+        elif args.get("lang", "en")=="zh":
+            generateDomain = GenerateDomain(params=args)
+        generateDomain.run()
+    elif args.get("command","")=="search":
+        serachdomain = SearchDomain(params=args, debug=True, export_all=True) 
+        serachdomain.run()
+    elif args.get("command","")=="version":
+        # print(__verison__)
+        pass
+    else:
+        print("please input command: generate, search")
+        print(args.get('command',""))
+        sys.exit(1)

+ 156 - 0
poetry.lock

@@ -0,0 +1,156 @@
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+
+[[package]]
+name = "altgraph"
+version = "0.17.4"
+description = "Python graph (network) package"
+optional = false
+python-versions = "*"
+files = [
+    {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
+    {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
+]
+
+[[package]]
+name = "future"
+version = "1.0.0"
+description = "Clean single-source support for Python 3 and 2"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"},
+    {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"},
+]
+
+[[package]]
+name = "macholib"
+version = "1.16.3"
+description = "Mach-O header analysis and editing"
+optional = false
+python-versions = "*"
+files = [
+    {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
+    {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
+]
+
+[package.dependencies]
+altgraph = ">=0.17"
+
+[[package]]
+name = "packaging"
+version = "24.0"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
+    {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
+]
+
+[[package]]
+name = "pefile"
+version = "2023.2.7"
+description = "Python PE parsing module"
+optional = false
+python-versions = ">=3.6.0"
+files = [
+    {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"},
+    {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
+]
+
+[[package]]
+name = "pyinstaller"
+version = "6.6.0"
+description = "PyInstaller bundles a Python application and all its dependencies into a single package."
+optional = false
+python-versions = "<3.13,>=3.8"
+files = [
+    {file = "pyinstaller-6.6.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d2705efe79f8749526f65c4bce70ae88eea8b6adfb051f123122e86542fe3802"},
+    {file = "pyinstaller-6.6.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:2aa771693ee3e0a899be3e9d946a24eab9896a98d0d4035f05a22f1193004cfb"},
+    {file = "pyinstaller-6.6.0-py3-none-manylinux2014_i686.whl", hash = "sha256:1fc15e8cebf76361568359a40926aa5746fc0a84ca365fb2ac6caeea014a2cd3"},
+    {file = "pyinstaller-6.6.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:7c4a55a5d872c118bc7a5e641c2df46ad18585c002d96adad129b4ee8c104463"},
+    {file = "pyinstaller-6.6.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:97197593344f11f3dd2bdadbab14c61fbc4cdf9cc692a89b047cb671764c1824"},
+    {file = "pyinstaller-6.6.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:00d81ddeee97710245a7ed03b0f9d5a4daf6c3a07adf978487b10991e1e20470"},
+    {file = "pyinstaller-6.6.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:b7cab21db6fcfbdab47ee960239d1b44cd95383a4463177bd592613941d67959"},
+    {file = "pyinstaller-6.6.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:00996d2090734d9ae4a1e53ed40351b07d593c37118d3e0d435bbcfa8db9edee"},
+    {file = "pyinstaller-6.6.0-py3-none-win32.whl", hash = "sha256:cfe3ed214601de0723cb660994b44934efacb77a1cf0e4cc5133da996bcf36ce"},
+    {file = "pyinstaller-6.6.0-py3-none-win_amd64.whl", hash = "sha256:e2f55fbbdf8a99ea84b39bc5669a68624473c303486d7eb2cd9063b339f0aa28"},
+    {file = "pyinstaller-6.6.0-py3-none-win_arm64.whl", hash = "sha256:abbd591967593dab264bcc3bcb2466c0a1582f19a112e37e916c4212069c7933"},
+    {file = "pyinstaller-6.6.0.tar.gz", hash = "sha256:be6bc2c3073d3e84fb7148d3af33ce9b6a7f01cfb154e06314cd1d4c05798a32"},
+]
+
+[package.dependencies]
+altgraph = "*"
+macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
+packaging = ">=22.0"
+pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""}
+pyinstaller-hooks-contrib = ">=2024.3"
+pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""}
+setuptools = ">=42.0.0"
+
+[package.extras]
+completion = ["argcomplete"]
+hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
+
+[[package]]
+name = "pyinstaller-hooks-contrib"
+version = "2024.5"
+description = "Community maintained hooks for PyInstaller"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pyinstaller_hooks_contrib-2024.5-py2.py3-none-any.whl", hash = "sha256:0852249b7fb1e9394f8f22af2c22fa5294c2c0366157969f98c96df62410c4c6"},
+    {file = "pyinstaller_hooks_contrib-2024.5.tar.gz", hash = "sha256:aa5dee25ea7ca317ad46fa16b5afc8dba3b0e43f2847e498930138885efd3cab"},
+]
+
+[package.dependencies]
+packaging = ">=22.0"
+setuptools = ">=42.0.0"
+
+[[package]]
+name = "python-whois"
+version = "0.8.0"
+description = "Whois querying and parsing of domain registration information."
+optional = false
+python-versions = "*"
+files = [
+    {file = "python-whois-0.8.0.tar.gz", hash = "sha256:dd336d3517eace2a7689406db7bb96ada3c5e74327423151aeee3e64225f6220"},
+]
+
+[package.dependencies]
+future = "*"
+
+[package.extras]
+"better date conversion" = ["python-dateutil"]
+
+[[package]]
+name = "pywin32-ctypes"
+version = "0.2.2"
+description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
+    {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
+]
+
+[[package]]
+name = "setuptools"
+version = "69.5.1"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"},
+    {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+
+[metadata]
+lock-version = "2.0"
+python-versions = ">=3.12,<3.13"
+content-hash = "c7e62ff041cfe41f0aa188f376169281d0468510a81ba4bd22e1d10463bd0c71"

+ 18 - 0
pyproject.toml

@@ -0,0 +1,18 @@
+[tool.poetry]
+name = "searchdomain-python"
+version = "0.1.0"
+description = ""
+authors = ["fish <zz1036@qq.com>"]
+readme = "README.md"
+
+[tool.poetry.dependencies]
+python = ">=3.12,<3.13"
+python-whois = "0.8.0"
+
+
+[tool.poetry.group.dev.dependencies]
+pyinstaller = "^6.6.0"
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"

+ 0 - 7
requirements.txt

@@ -1,8 +1 @@
 python-whois==0.8.0
-
-
-
-
-
-
-

+ 10 - 0
scripts/build.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+# @Contact :   liuyuqi.gov@msn.cn
+# @Time    :   2024/04/26 16:02:37
+# @License :   (C)Copyright 2022 liuyuqi.
+# @Desc    :   build binary file
+###############################################################################
+
+# poetry install
+# poetry shell
+pyinstaller  -F -c  --name search_domain main.py

+ 51 - 0
scripts/start.bat

@@ -0,0 +1,51 @@
+@echo off
+REM ***************************************************************************
+REM @Contact :   liuyuqi.gov@msn.cn
+REM @Time    :   2024/04/26 16:02:11
+REM @Version :   1.0
+REM @License :   (C)Copyright 2019 liuyuqi.
+REM @Desc    :   调用 search_domain.exe 查询域名,本脚本提示用户输入相应的参数启动程序
+REM %1 - ext_name
+REM %2 - characters replaced
+REM %3 - new characters
+REM ***************************************************************************
+
+
+REM 1. 打印help
+:help
+echo 请输入相应的参数启动程序
+echo 1. 生成域名
+echo 2. 检索域名
+set /p input=请输入相应的参数:
+if "%input%"=="1" goto make_domain
+if "%input%"=="2" goto search_domain
+goto help
+
+REM 2. 生成域名
+:make_domain
+echo 请输入域名长度:
+set /p length=请输入域名长度:
+echo 请输入域名后缀:
+set /p ext_name=请输入域名后缀:
+echo 请输入替换字符:
+set /p characters=请输入替换字符:
+echo 请输入新字符:
+set /p new_characters=请输入新字符:
+echo 生成域名中...
+search_domain.exe make %ext_name% %characters% %new_characters% %length%
+pause
+goto help
+
+REM 3. 检索域名
+:search_domain
+echo 请输入域名后缀:
+set /p ext_name=请输入域名后缀:
+echo 请输入替换字符:
+set /p characters=请输入替换字符:
+echo 请输入新字符:
+set /p new_characters=请输入新字符:
+echo 检索域名中...
+search_domain.exe search %ext_name% %characters% %new_characters%
+
+
+pause

+ 1 - 1
searchdomain/config.py

@@ -17,4 +17,4 @@ config= {
     "default": DevelopmentConfig,
     "develop": DevelopmentConfig,
     "production": ProductionConfig
-}
+}

+ 1 - 2
searchdomain/domain_notify.py

@@ -1,9 +1,8 @@
 import whois
 from concurrent.futures import ThreadPoolExecutor
-import os,sys,re,json
-# import requests
 import time
 from .push import EmailPush
+
 class DomainNotify(object):
     """域名到期推送"""
     def __init__(self):

+ 12 - 5
searchdomain/generate_domain.py

@@ -14,15 +14,19 @@ import csv
 
 class GenerateDomain(object):
     
-    def __init__(self):
+    def __init__(self, params: dict,):
         '''初始化列表'''
         self.initPinYin=[]
-        self.composePinYin=[]
+        self.params = params
+        self.keyword= self.params['keyword'].split(',')
         # self.yuming=["com","cn","me","net"]
-        self.yuming=["com"]
+        self.yuming = self.params["domain"].split(',')
+
+        self.composePinYin=[]
         self.composeDomain=[]
 
     def run(self):
+        """ 批量生成域名, 保存到 domain.txt """
         with open(("data/a.csv"), "r", encoding="utf-8") as f:
             csv_data = csv.reader(f)
             for row in csv_data:
@@ -31,8 +35,11 @@ class GenerateDomain(object):
                         self.initPinYin.append(pinyin)
 
             for i in self.initPinYin:
-                for j in self.initPinYin:
-                    self.composePinYin.append(i+j)
+                for j in self.keyword:
+                    if self.params["position"]=="prefix":
+                        self.composePinYin.append(i+j)
+                    else:
+                        self.composePinYin.append(j+i)
 
             for i in self.composePinYin:
                 for j in self.yuming:

+ 12 - 8
searchdomain/generate_en_domain.py

@@ -14,26 +14,30 @@ import csv
 
 class GenerateEnDomain(object):
     
-    def __init__(self):
+    def __init__(self, params: dict):
         '''初始化列表'''
         self.initList=[]
+        self.params =params
         # self.keyword=["chat","ai"] # chat+xx
-        self.keyword=["ai"] # xx + ai
-        self.composePinYin=[]
+        
+        self.keyword= self.params['keyword'].split(',')
         # self.yuming=["com","cn","me","net","co","run","wiki","tech","org","info","vip","cc","app","io","one","tk","xyz"]
-        self.yuming=["com"]
+        self.yuming=self.params["domain"].split(',')
         self.composeDomain=[]
+        self.composePinYin=[]
 
     def run(self):
-        with open(("res3.csv"), "r", encoding="utf-8") as f:
+        with open((r"data/b.csv"), "r", encoding="utf-8") as f:
             csv_data = f.readlines()
             for row in csv_data:
                 self.initList.append(row.strip())
-
+            
             for i in self.initList:
                 for j in self.keyword:
-                    self.composePinYin.append(i+j)
-                    # self.composePinYin.append(j+i)
+                    if self.params['position']=="prefix":
+                        self.composePinYin.append(i+j)
+                    else:
+                        self.composePinYin.append(j+i)
 
             for i in self.composePinYin:
                 for j in self.yuming:

+ 41 - 0
searchdomain/options.py

@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+"""
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2024/06/22
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   command line params or config from file
+"""
+
+import sys,os,re
+import argparse
+from collections import OrderedDict
+
+def parse_args():
+    parser = argparse.ArgumentParser(description='search domain')
+    parser.add_argument('command',  help='command: generate, search', choices=['generate','search', 'help','version'] , default='help')
+    parser.add_argument('--export_all', action='store_true', help='export all domain')
+    parser.add_argument(
+        "--input", help="set input domain list file,eg: domain.txt", type=str, default="domain.txt")
+    parser.add_argument(
+        "--output", help="set output domain result list file,eg: result.txt", type=str, default="result.txt")
+        
+    parser.add_argument('--lang', choices=['zh', 'en'], default='en',help='language')
+    parser.add_argument('--domain', default='com',help='input some domain, plilt with ","')
+    parser.add_argument('--keyword', default='', help='input some keyword, spilt with ","')
+    parser.add_argument('--position', default='prefix',choices=['prefix', 'suffix'], help='choose generate str positon')
+    args = parser.parse_args()
+
+    # remove None
+    command_line_conf = OrderedDict(
+        {k: v for k, v in args.__dict__.items() if v is not None}
+    )
+    system_conf = user_conf = custom_conf = OrderedDict()
+    system_conf.update(command_line_conf)
+    return system_conf
+
+def _read_custom_conf(config_path: str) -> OrderedDict:
+    pass
+
+def _read_user_conf() -> OrderedDict:
+    pass

+ 5 - 16
searchdomain/searchdomain.py

@@ -1,18 +1,13 @@
 import whois
 from concurrent.futures import ThreadPoolExecutor
-import os
-import sys
-import re
-import json
 import logging
 import argparse
 from . import db
 
-
 class SearchDomain(object):
     """search avaliable domain and save result"""
 
-    def __init__(self, debug=False, export_all=False):
+    def __init__(self, params: dict, debug=False, export_all=True):
         '''
         初始化
         debug 调试模式
@@ -20,17 +15,10 @@ class SearchDomain(object):
         return:
         '''
         super(SearchDomain, self).__init__()
+        self.params = params
         self.export_all=export_all
-        parser = argparse.ArgumentParser(description='Demo of argparse')
-        parser.add_argument(
-            "--input", help="set input domain list file,eg: domain.txt", type=str, default="domain.txt")
-        parser.add_argument(
-            "--output", help="set output domain result list file,eg: result.txt", type=str, default="result.txt")
-        args = parser.parse_args()
-        if args.input:
-            self.input = args.input
-        if args.output:
-            self.output = args.output
+        self.input=params["input"]
+        self.output=params["output"]
         if debug == True:
             logging.basicConfig(level=logging.DEBUG)
 
@@ -58,6 +46,7 @@ class SearchDomain(object):
                 self.saveRes(domain, res)
 
     def saveRes(self, domain: str, res: bool):
+        """ save result to file """
         # db.Mysql().save()
         db.File().save(self.output, domain + "    " + str(res))
 

+ 0 - 0
searchdomain/utils/__init__.py


+ 44 - 0
searchdomain/utils/domain_util.py

@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+"""
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2024/04/26
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   域名工具
+"""
+import whois
+from concurrent.futures import ThreadPoolExecutor
+
+class DomainUtil(object):
+    """域名工具"""
+    def __init__(self):
+        super(DomainUtil,self).__init__()
+    
+    @staticmethod
+    def get_expiration_date(domain:str)->None:
+        '''
+        检测域名是否快到期
+        :params domain 域名:
+        :return true or false'''
+        try:
+            whi = whois.whois(domain)
+            expirationDate= whi.expiration_date
+            return expirationDate
+        except Exception as e:
+            print(e)
+        return None
+
+    @staticmethod
+    def is_available(domain: str)->None:
+        '''
+        检测域名是否可用
+        :params domain 域名:
+        :return true or false'''
+        try:
+            whi = whois.whois(domain)
+            return False
+        except Exception as e:
+            if(str(e).index("No match") == 0):
+                return True
+            else:
+                return False

+ 11 - 0
test/args_test.py

@@ -0,0 +1,11 @@
+import argparse
+
+def parse_args():
+    parser = argparse.ArgumentParser(description='search domain')
+    parser.add_argument('command',  help='command: generate, search', choices=['generate','search'] , default='generate')
+    parser.add_argument('--export_all', action='store_true', help='export all domain')
+    return parser.parse_args()
+
+if __name__=='__main__':
+    args = parse_args()
+    print(args)