HoneyTian commited on
Commit
f25c867
1 Parent(s): 31eb46e
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.wav filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .git/
3
+ .idea/
4
+
5
+ /data/
6
+ /dotenv/
7
+ /logs/
8
+ /trained_models
9
+
10
+ **/__pycache__/
11
+
12
+ #**/*.wav
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ WORKDIR /code
4
+
5
+ COPY . /code
6
+
7
+ RUN pip install --upgrade pip
8
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
9
+
10
+ RUN bash install.sh --stage 0 --stop_stage 0
11
+
12
+ RUN useradd -m -u 1000 user
13
+
14
+ USER user
15
+
16
+ ENV HOME=/home/user \
17
+ PATH=/home/user/.local/bin:$PATH
18
+
19
+ WORKDIR $HOME/app
20
+
21
+ COPY --chown=user . $HOME/app
22
+
23
+ CMD ["python3", "main.py"]
description.md ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ ## 描述
2
+
3
+ ```text
4
+ 电子书网站
5
+ http://www.wenxue100.com
6
+ ```
examples/paragraph/paragraph_to_sentence.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import argparse
4
+
5
+ import spacy
6
+
7
+ from project_settings import project_path
8
+
9
+
10
+ def get_args():
11
+ parser = argparse.ArgumentParser()
12
+ parser.add_argument(
13
+ "--txt_file",
14
+ default=(project_path / "data/e_book/confucianism/the_analects.txt").as_posix(),
15
+ type=str
16
+ )
17
+ args = parser.parse_args()
18
+ return args
19
+
20
+
21
+ def main():
22
+ args = get_args()
23
+
24
+ with open(args.txt_file, "r", encoding="utf-8") as f:
25
+ data = f.read()
26
+
27
+ # print(data)
28
+
29
+ nlp = spacy.load("zh_core_web_sm")
30
+
31
+ doc = nlp(data)
32
+
33
+ for sentence in doc.sents:
34
+ text = sentence.text.strip()
35
+ if len(text) == 0:
36
+ continue
37
+ print(text)
38
+ print("-" * 150)
39
+ return
40
+
41
+
42
+ if __name__ == '__main__':
43
+ main()
examples/tts/edge-tts/edge-tts.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import argparse
4
+ import asyncio
5
+ import tempfile
6
+
7
+ import edge_tts
8
+
9
+ from project_settings import project_path
10
+
11
+
12
+ def get_args():
13
+ parser = argparse.ArgumentParser()
14
+ parser.add_argument(
15
+ "--text",
16
+ default="学而时习之,不亦悦乎。",
17
+ type=str
18
+ )
19
+ parser.add_argument(
20
+ "--speaker",
21
+ default="zh-CN-XiaoxiaoNeural",
22
+ type=str
23
+ )
24
+ args = parser.parse_args()
25
+ return args
26
+
27
+
28
+ async def print_edge_voices():
29
+ voices = await edge_tts.list_voices()
30
+ for voice in voices:
31
+ print(voice)
32
+
33
+
34
+ async def edge_text_to_speech(text: str, speaker: str):
35
+ communicate = edge_tts.Communicate(text, speaker)
36
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file:
37
+ tmp_path = tmp_file.name
38
+ await communicate.save(tmp_path)
39
+ print(tmp_path)
40
+ return f"Speech synthesis completed for: {text}", tmp_path
41
+
42
+
43
+ def main():
44
+ args = get_args()
45
+
46
+ loop = asyncio.get_event_loop()
47
+
48
+ loop.run_until_complete(print_edge_voices())
49
+
50
+ loop.run_until_complete(edge_text_to_speech(
51
+ text=args.text,
52
+ speaker=args.speaker,
53
+ ))
54
+
55
+ return
56
+
57
+
58
+ if __name__ == '__main__':
59
+ main()
install.sh ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # sh install.sh --stage 0 --stop_stage 0 --system_version windows
4
+
5
+ verbose=true;
6
+ stage=-1
7
+ stop_stage=0
8
+
9
+
10
+ # parse options
11
+ while true; do
12
+ [ -z "${1:-}" ] && break; # break if there are no arguments
13
+ case "$1" in
14
+ --*) name=$(echo "$1" | sed s/^--// | sed s/-/_/g);
15
+ eval '[ -z "${'"$name"'+xxx}" ]' && echo "$0: invalid option $1" 1>&2 && exit 1;
16
+ old_value="(eval echo \\$$name)";
17
+ if [ "${old_value}" == "true" ] || [ "${old_value}" == "false" ]; then
18
+ was_bool=true;
19
+ else
20
+ was_bool=false;
21
+ fi
22
+
23
+ # Set the variable to the right value-- the escaped quotes make it work if
24
+ # the option had spaces, like --cmd "queue.pl -sync y"
25
+ eval "${name}=\"$2\"";
26
+
27
+ # Check that Boolean-valued arguments are really Boolean.
28
+ if $was_bool && [[ "$2" != "true" && "$2" != "false" ]]; then
29
+ echo "$0: expected \"true\" or \"false\": $1 $2" 1>&2
30
+ exit 1;
31
+ fi
32
+ shift 2;
33
+ ;;
34
+
35
+ *) break;
36
+ esac
37
+ done
38
+
39
+ work_dir="$(pwd)"
40
+ data_dir="$(pwd)/data"
41
+
42
+ mkdir -p "${data_dir}"
43
+
44
+ if [ ${stage} -le 0 ] && [ ${stop_stage} -ge 0 ]; then
45
+ $verbose && echo "stage 0: download trained models"
46
+ cd "${work_dir}" || exit 1;
47
+
48
+ mkdir -p trained_models && cd trained_models || exit 1;
49
+
50
+ python -m spacy download zh_core_web_sm
51
+
52
+ fi
log.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import logging
4
+ from logging.handlers import TimedRotatingFileHandler
5
+ import os
6
+
7
+
8
+ def setup(log_directory: str):
9
+ fmt = "%(asctime)s - %(name)s - %(levelname)s %(filename)s:%(lineno)d > %(message)s"
10
+
11
+ stream_handler = logging.StreamHandler()
12
+ stream_handler.setLevel(logging.INFO)
13
+ stream_handler.setFormatter(logging.Formatter(fmt))
14
+
15
+ # main
16
+ main_logger = logging.getLogger("main")
17
+ main_logger.addHandler(stream_handler)
18
+ main_info_file_handler = TimedRotatingFileHandler(
19
+ filename=os.path.join(log_directory, "main.log"),
20
+ encoding="utf-8",
21
+ when="midnight",
22
+ interval=1,
23
+ backupCount=30
24
+ )
25
+ main_info_file_handler.setLevel(logging.INFO)
26
+ main_info_file_handler.setFormatter(logging.Formatter(fmt))
27
+ main_logger.addHandler(main_info_file_handler)
28
+
29
+ # http
30
+ http_logger = logging.getLogger("http")
31
+ http_file_handler = TimedRotatingFileHandler(
32
+ filename=os.path.join(log_directory, "http.log"),
33
+ encoding='utf-8',
34
+ when="midnight",
35
+ interval=1,
36
+ backupCount=30
37
+ )
38
+ http_file_handler.setLevel(logging.DEBUG)
39
+ http_file_handler.setFormatter(logging.Formatter(fmt))
40
+ http_logger.addHandler(http_file_handler)
41
+
42
+ # api
43
+ api_logger = logging.getLogger("api")
44
+ api_file_handler = TimedRotatingFileHandler(
45
+ filename=os.path.join(log_directory, "api.log"),
46
+ encoding='utf-8',
47
+ when="midnight",
48
+ interval=1,
49
+ backupCount=30
50
+ )
51
+ api_file_handler.setLevel(logging.DEBUG)
52
+ api_file_handler.setFormatter(logging.Formatter(fmt))
53
+ api_logger.addHandler(api_file_handler)
54
+
55
+ # alarm
56
+ alarm_logger = logging.getLogger("alarm")
57
+ alarm_file_handler = TimedRotatingFileHandler(
58
+ filename=os.path.join(log_directory, "alarm.log"),
59
+ encoding="utf-8",
60
+ when="midnight",
61
+ interval=1,
62
+ backupCount=30
63
+ )
64
+ alarm_file_handler.setLevel(logging.DEBUG)
65
+ alarm_file_handler.setFormatter(logging.Formatter(fmt))
66
+ alarm_logger.addHandler(alarm_file_handler)
67
+
68
+ debug_file_handler = TimedRotatingFileHandler(
69
+ filename=os.path.join(log_directory, "debug.log"),
70
+ encoding="utf-8",
71
+ when="D",
72
+ interval=1,
73
+ backupCount=7
74
+ )
75
+ debug_file_handler.setLevel(logging.DEBUG)
76
+ debug_file_handler.setFormatter(logging.Formatter(fmt))
77
+
78
+ info_file_handler = TimedRotatingFileHandler(
79
+ filename=os.path.join(log_directory, "info.log"),
80
+ encoding="utf-8",
81
+ when="D",
82
+ interval=1,
83
+ backupCount=7
84
+ )
85
+ info_file_handler.setLevel(logging.INFO)
86
+ info_file_handler.setFormatter(logging.Formatter(fmt))
87
+
88
+ error_file_handler = TimedRotatingFileHandler(
89
+ filename=os.path.join(log_directory, "error.log"),
90
+ encoding="utf-8",
91
+ when="D",
92
+ interval=1,
93
+ backupCount=7
94
+ )
95
+ error_file_handler.setLevel(logging.ERROR)
96
+ error_file_handler.setFormatter(logging.Formatter(fmt))
97
+
98
+ logging.basicConfig(
99
+ level=logging.DEBUG,
100
+ datefmt="%a, %d %b %Y %H:%M:%S",
101
+ handlers=[
102
+ debug_file_handler,
103
+ info_file_handler,
104
+ error_file_handler,
105
+ ]
106
+ )
107
+
108
+
109
+ if __name__ == "__main__":
110
+ pass
main.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import argparse
4
+ import asyncio
5
+ from functools import partial
6
+ import logging
7
+ from pathlib import Path
8
+ import platform
9
+ import re
10
+ import tempfile
11
+ from typing import List
12
+
13
+ from project_settings import project_path, log_directory
14
+ import log
15
+
16
+ log.setup(log_directory=log_directory)
17
+
18
+ import anyio
19
+ import edge_tts
20
+ import gradio as gr
21
+
22
+ from toolbox.os.command import Command
23
+
24
+ main_logger = logging.getLogger("main")
25
+
26
+
27
+ def get_args():
28
+ parser = argparse.ArgumentParser()
29
+
30
+ parser.add_argument(
31
+ "--example_wav_dir",
32
+ default=(project_path / "data/examples").as_posix(),
33
+ type=str
34
+ )
35
+ args = parser.parse_args()
36
+ return args
37
+
38
+
39
+ async def edge_tts_get_speakers() -> List[str]:
40
+ edge_tts_speakers_choices = list()
41
+ voices = await edge_tts.list_voices()
42
+ for voice in voices:
43
+ short_name = voice["ShortName"]
44
+ edge_tts_speakers_choices.append(short_name)
45
+ return edge_tts_speakers_choices
46
+
47
+
48
+ async def edge_tts_text_to_speech(text: str, speaker: str):
49
+ communicate = edge_tts.Communicate(text, speaker)
50
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file:
51
+ tmp_path = tmp_file.name
52
+ await communicate.save(tmp_path)
53
+
54
+ return tmp_path
55
+
56
+
57
+ def shell(cmd: str):
58
+ return Command.popen(cmd)
59
+
60
+
61
+ def main():
62
+ args = get_args()
63
+
64
+ title = "## 电子书阅读."
65
+
66
+ loop = asyncio.get_event_loop()
67
+ edge_tts_speakers_choices = loop.run_until_complete(edge_tts_get_speakers())
68
+
69
+ # blocks
70
+ with gr.Blocks() as blocks:
71
+ gr.Markdown(value=title)
72
+
73
+ with gr.Tabs():
74
+ with gr.TabItem("Edge TTS"):
75
+ edge_tts_text = gr.Textbox(value="学而时习之,不亦悦乎。", lines=4, max_lines=50, label="text")
76
+ edge_tts_speaker = gr.Dropdown(choices=edge_tts_speakers_choices, value=edge_tts_speakers_choices[0], label="speakers")
77
+
78
+ edge_tts_audio = gr.Audio(type="filepath", label="audio")
79
+
80
+ edge_tts_button = gr.Button(value="edge_tts", variant="primary")
81
+ edge_tts_button.click(
82
+ edge_tts_text_to_speech,
83
+ inputs=[
84
+ edge_tts_text,
85
+ edge_tts_speaker,
86
+ ],
87
+ outputs=[
88
+ edge_tts_audio
89
+ ],
90
+ )
91
+ with gr.TabItem("shell"):
92
+ shell_text = gr.Textbox(label="cmd")
93
+ shell_button = gr.Button("run")
94
+ shell_output = gr.Textbox(label="output")
95
+
96
+ shell_button.click(
97
+ shell,
98
+ inputs=[
99
+ shell_text,
100
+ ],
101
+ outputs=[
102
+ shell_output
103
+ ],
104
+ )
105
+
106
+ launch = partial(
107
+ blocks.queue().launch,
108
+ share=False if platform.system() == "Windows" else False,
109
+ server_name="127.0.0.1" if platform.system() == "Windows" else "0.0.0.0",
110
+ server_port=7860,
111
+ )
112
+ anyio.run(
113
+ launch,
114
+ backend="asyncio"
115
+ )
116
+ return
117
+
118
+
119
+ if __name__ == "__main__":
120
+ main()
project_settings.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import os
4
+ from pathlib import Path
5
+
6
+ from toolbox.os.environment import EnvironmentManager
7
+
8
+
9
+ project_path = os.path.abspath(os.path.dirname(__file__))
10
+ project_path = Path(project_path)
11
+
12
+ log_directory = project_path / "logs"
13
+ log_directory.mkdir(parents=True, exist_ok=True)
14
+
15
+ temp_directory = project_path / "temp"
16
+ temp_directory.mkdir(parents=True, exist_ok=True)
17
+
18
+ environment = EnvironmentManager(
19
+ path=os.path.join(project_path, "dotenv"),
20
+ env=os.environ.get("environment", "dev"),
21
+ )
22
+
23
+
24
+ if __name__ == '__main__':
25
+ pass
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio==4.38.1
2
+ python-dotenv==1.0.1
3
+ spacy==3.7.5
4
+ edge-tts==6.1.12
toolbox/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/json/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/json/misc.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ from typing import Callable
4
+
5
+
6
+ def traverse(js, callback: Callable, *args, **kwargs):
7
+ if isinstance(js, list):
8
+ result = list()
9
+ for l in js:
10
+ l = traverse(l, callback, *args, **kwargs)
11
+ result.append(l)
12
+ return result
13
+ elif isinstance(js, tuple):
14
+ result = list()
15
+ for l in js:
16
+ l = traverse(l, callback, *args, **kwargs)
17
+ result.append(l)
18
+ return tuple(result)
19
+ elif isinstance(js, dict):
20
+ result = dict()
21
+ for k, v in js.items():
22
+ k = traverse(k, callback, *args, **kwargs)
23
+ v = traverse(v, callback, *args, **kwargs)
24
+ result[k] = v
25
+ return result
26
+ elif isinstance(js, int):
27
+ return callback(js, *args, **kwargs)
28
+ elif isinstance(js, str):
29
+ return callback(js, *args, **kwargs)
30
+ else:
31
+ return js
32
+
33
+
34
+ def demo1():
35
+ d = {
36
+ "env": "ppe",
37
+ "mysql_connect": {
38
+ "host": "$mysql_connect_host",
39
+ "port": 3306,
40
+ "user": "callbot",
41
+ "password": "NxcloudAI2021!",
42
+ "database": "callbot_ppe",
43
+ "charset": "utf8"
44
+ },
45
+ "es_connect": {
46
+ "hosts": ["10.20.251.8"],
47
+ "http_auth": ["elastic", "ElasticAI2021!"],
48
+ "port": 9200
49
+ }
50
+ }
51
+
52
+ def callback(s):
53
+ if isinstance(s, str) and s.startswith('$'):
54
+ return s[1:]
55
+ return s
56
+
57
+ result = traverse(d, callback=callback)
58
+ print(result)
59
+ return
60
+
61
+
62
+ if __name__ == '__main__':
63
+ demo1()
toolbox/os/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/os/command.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import os
4
+
5
+
6
+ class Command(object):
7
+ custom_command = [
8
+ "cd"
9
+ ]
10
+
11
+ @staticmethod
12
+ def _get_cmd(command):
13
+ command = str(command).strip()
14
+ if command == "":
15
+ return None
16
+ cmd_and_args = command.split(sep=" ")
17
+ cmd = cmd_and_args[0]
18
+ args = " ".join(cmd_and_args[1:])
19
+ return cmd, args
20
+
21
+ @classmethod
22
+ def popen(cls, command):
23
+ cmd, args = cls._get_cmd(command)
24
+ if cmd in cls.custom_command:
25
+ method = getattr(cls, cmd)
26
+ return method(args)
27
+ else:
28
+ resp = os.popen(command)
29
+ result = resp.read()
30
+ resp.close()
31
+ return result
32
+
33
+ @classmethod
34
+ def cd(cls, args):
35
+ if args.startswith("/"):
36
+ os.chdir(args)
37
+ else:
38
+ pwd = os.getcwd()
39
+ path = os.path.join(pwd, args)
40
+ os.chdir(path)
41
+
42
+ @classmethod
43
+ def system(cls, command):
44
+ return os.system(command)
45
+
46
+ def __init__(self):
47
+ pass
48
+
49
+
50
+ def ps_ef_grep(keyword: str):
51
+ cmd = "ps -ef | grep {}".format(keyword)
52
+ rows = Command.popen(cmd)
53
+ rows = str(rows).split("\n")
54
+ rows = [row for row in rows if row.__contains__(keyword) and not row.__contains__("grep")]
55
+ return rows
56
+
57
+
58
+ if __name__ == "__main__":
59
+ pass
toolbox/os/environment.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import json
4
+ import os
5
+
6
+ from dotenv import load_dotenv
7
+ from dotenv.main import DotEnv
8
+
9
+ from toolbox.json.misc import traverse
10
+
11
+
12
+ class EnvironmentManager(object):
13
+ def __init__(self, path, env, override=False):
14
+ filename = os.path.join(path, '{}.env'.format(env))
15
+ self.filename = filename
16
+
17
+ load_dotenv(
18
+ dotenv_path=filename,
19
+ override=override
20
+ )
21
+
22
+ self._environ = dict()
23
+
24
+ def open_dotenv(self, filename: str = None):
25
+ filename = filename or self.filename
26
+ dotenv = DotEnv(
27
+ dotenv_path=filename,
28
+ stream=None,
29
+ verbose=False,
30
+ interpolate=False,
31
+ override=False,
32
+ encoding="utf-8",
33
+ )
34
+ result = dotenv.dict()
35
+ return result
36
+
37
+ def get(self, key, default=None, dtype=str):
38
+ result = os.environ.get(key)
39
+ if result is None:
40
+ if default is None:
41
+ result = None
42
+ else:
43
+ result = default
44
+ else:
45
+ result = dtype(result)
46
+ self._environ[key] = result
47
+ return result
48
+
49
+
50
+ _DEFAULT_DTYPE_MAP = {
51
+ 'int': int,
52
+ 'float': float,
53
+ 'str': str,
54
+ 'json.loads': json.loads
55
+ }
56
+
57
+
58
+ class JsonConfig(object):
59
+ """
60
+ 将 json 中, 形如 `$float:threshold` 的值, 处理为:
61
+ 从环境变量中查到 threshold, 再将其转换为 float 类型.
62
+ """
63
+ def __init__(self, dtype_map: dict = None, environment: EnvironmentManager = None):
64
+ self.dtype_map = dtype_map or _DEFAULT_DTYPE_MAP
65
+ self.environment = environment or os.environ
66
+
67
+ def sanitize_by_filename(self, filename: str):
68
+ with open(filename, 'r', encoding='utf-8') as f:
69
+ js = json.load(f)
70
+
71
+ return self.sanitize_by_json(js)
72
+
73
+ def sanitize_by_json(self, js):
74
+ js = traverse(
75
+ js,
76
+ callback=self.sanitize,
77
+ environment=self.environment
78
+ )
79
+ return js
80
+
81
+ def sanitize(self, string, environment):
82
+ """支持 $ 符开始的, 环境变量配置"""
83
+ if isinstance(string, str) and string.startswith('$'):
84
+ dtype, key = string[1:].split(':')
85
+ dtype = self.dtype_map[dtype]
86
+
87
+ value = environment.get(key)
88
+ if value is None:
89
+ raise AssertionError('environment not exist. key: {}'.format(key))
90
+
91
+ value = dtype(value)
92
+ result = value
93
+ else:
94
+ result = string
95
+ return result
96
+
97
+
98
+ def demo1():
99
+ import json
100
+
101
+ from project_settings import project_path
102
+
103
+ environment = EnvironmentManager(
104
+ path=os.path.join(project_path, 'server/callbot_server/dotenv'),
105
+ env='dev',
106
+ )
107
+ init_scenes = environment.get(key='init_scenes', dtype=json.loads)
108
+ print(init_scenes)
109
+ print(environment._environ)
110
+ return
111
+
112
+
113
+ if __name__ == '__main__':
114
+ demo1()
toolbox/os/other.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import inspect
3
+
4
+
5
+ def pwd():
6
+ """你在哪个文件调用此函数, 它就会返回那个文件所在的 dir 目标"""
7
+ frame = inspect.stack()[1]
8
+ module = inspect.getmodule(frame[0])
9
+ return os.path.dirname(os.path.abspath(module.__file__))