Skip to content

Commit 0a3c7ee

Browse files
committed
UPDATED: fixed #6 & Separate process for resolves #7
1 parent 438ab76 commit 0a3c7ee

File tree

8 files changed

+306
-203
lines changed

8 files changed

+306
-203
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ python cvemysql.py [-u user] [-p password] [-y year] [output_name] [--cofigurati
5454
`[-t tablename]` 테이블 이름을 미리 설정합니다. 기본값은 `NVD_NIST_TABLE`입니다.<br>
5555
`[-c content]` 리스트 컨텐츠을 선택합니다. 현재는 해당 인자를 사용하지 않아도 자동으로 `NVD_NIST`로 기본 설정되어 있습니다.<br> Available type - nvd, mitre<br>
5656
`[-select-path]` 외부에서 RAW 파일을 다운로드 하지 않고 이미 존재하는 해당 파일 경로로 지정합니다. `$JAVA_HOME`처럼 미리 지정된 환경 변수와 혼합하여 사용할 수 있습니다.<br>
57-
`[-tc thread_count]` 멀티쓰레드 갯수를 설정합니다. 기본값은 `4`입니다. 해당 값을 건드리는 것은 추천하지 않습니다.
57+
`[-tc thread_count]` 멀티쓰레드 갯수를 설정합니다. 입력하지 않을 경우, 자동으로 지정됩니다.<br>
5858
`[output_file]` 출력 타입 지정시, 추출될 파일명을 지정합니다. 출력 파일의 이름을 지정하는 것을 강력히 권장합니다. 확장자는 기재하지 않아도 되며, 만약 압축 확장자(.zip)가 붙어있다면, 추출된 파일들을 전부 압축하여 `zip` 파일로 만들어줍니다.<br>
5959

6060

@@ -63,7 +63,7 @@ python cvemysql.py [-u user] [-p password] [-y year] [output_name] [--cofigurati
6363
`[--db]` 데이터베이스 파일로 추출합니다. MySQL 기반에서는 SQL 파일이 기본 확장자입니다.<br>
6464
`[--csv]` 데이터베이스에 있는 데이터 값들을 CSV 파일로 추출합니다.<br>
6565
`[--setup-install]` 처음 실행할 때 모듈이 정상적으로 작동할 수 있도록 합니다. DEPRECATED.<br>
66-
66+
`[--max-thread]` 사용 가능한 최대 쓰레드 수로 지정합니다. 안정성을 위해 해당 인자는 권장하지 않습니다.<br>
6767
## Example
6868
아래는 해당 플랫폼을 사용하기 위해 입력하는 명령어의 예시들을 나열한 것입니다. 프로그램을 실행시킬 때 참조하시기 바랍니다.<br>
6969
예를 들어 특정 년도의 NVD-NIST CVE 리스트를 모두 가져와서 데이터베이스만 만들려면 다음과 같이 하십시오:

__unused__.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# -*- coding: utf-8 -*-
2+
import threading
3+
from threading import Thread
4+
5+
class ThreadList:
6+
def __init__(self, process):
7+
self._entry = 0
8+
self.total = 0
9+
self._wpList = []
10+
self.pList = []
11+
self._coreThread = None
12+
self._process = None
13+
self.kill = False
14+
self.process = process
15+
self._lock = threading.Lock()
16+
17+
def _pobject(self):
18+
self._entry = len(self._wpList)
19+
self._wpList.reverse()
20+
21+
while self.kill == False:
22+
for ps in range(0, self.process):
23+
try:
24+
v = self._wpList.pop()
25+
self.pList.append(v)
26+
except:
27+
if len(self._wpList) != 0:
28+
self.process = len(self._wpList) % self.process
29+
self._pobject()
30+
else:
31+
self.kill = True
32+
break
33+
34+
for p in self.pList:
35+
p.start()
36+
37+
for p in self.pList:
38+
p.join()
39+
40+
for p in self.pList:
41+
del p
42+
43+
self.pList.clear()
44+
45+
if len(self._wpList) == 0:
46+
self.kill = True
47+
48+
def _processFunction(self, delay=6.0):
49+
while True:
50+
sys.stdout.write("\rCurrent progress: %d / %d" % (self._entry - len(self._wpList), self._entry))
51+
sys.stdout.flush()
52+
if self.kill:
53+
self._lock.release()
54+
break
55+
time.sleep(delay)
56+
57+
def start(self):
58+
self._coreThread = Thread(target=self._pobject)
59+
self._coreThread.start()
60+
self._process = Thread(target=self._processFunction)
61+
self._process.start()
62+
self._lock.acquire()
63+
64+
def add_thread(self, thread):
65+
self._wpList.append(thread)

cvemitre.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ def load(self, obj):
5151
is_exist = True
5252
else:
5353
os.remove(raw_file)
54+
55+
if obj['specific_path'] is not None:
56+
raw_file = obj['specific_path'][0]
57+
print("USING: %s" % raw_file)
58+
is_exist = True
59+
5460
if not is_exist:
5561
target_url = url + raw_file
5662
print("Downloading the resource file ...")
@@ -60,7 +66,7 @@ def load(self, obj):
6066
if raw_type == "xml":
6167
readTo = ET.parse(raw_file).getroot()
6268
else:
63-
with open(raw_file, 'r', newline='', encoding='ISO-8859-1') as fs:
69+
with open(raw_file, 'r', newline='', encoding='utf-8') as fs:
6470
readTo = csv.reader(fs)
6571
for line in readTo:
6672
try:
@@ -124,4 +130,4 @@ def insert(self, obj):
124130
raise NotImplementedError("No need to execute")
125131

126132
def export(self, export_path_name="unspecified", export_type='sql', tablename="Unknown_table", option=None, charset='utf-8'):
127-
return super().export(export_path_name, export_type, tablename, option, "ISO-8859-1")
133+
return super().export(export_path_name, export_type, tablename, option, charset)

cvemysql.py

+24-9
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ def initialize(user, password, host, port, char="utf8"):
3333
database.connect()
3434
return database
3535

36-
def configure_task(base, table_name, year, output_name=None, specific_path=None):
36+
def configure_task(base, table_name, year, output_name=None, specific_path=None, thread_count=None):
3737
""" 작업을 구성합니다. """
3838

3939
# 작업을 위한 여러가지 환경 변수를 지정해줍니다.
4040
directory = {"year":year,
41-
"table_name":table_name, "output_name":output_name, "specific_path": specific_path}
41+
"table_name":table_name, "output_name":output_name, "specific_path": specific_path, "thread_count": thread_count}
4242

4343
# 데이터를 분석하고 이에 따른 결과값을 가져옵니다.
4444
filepath, collection = base.load(directory)
@@ -77,8 +77,6 @@ def help(error=None):
7777
if error is not None:
7878
raise CommandException(error)
7979

80-
thread_count = 8
81-
8280
if __name__ == "__main__":
8381

8482
# 특정 파일이 지정되지 않았을 때, 외부에서 CVE RAW 데이터에 해당하는 연도를 담을 리스트입니다.
@@ -88,21 +86,22 @@ def help(error=None):
8886
output_filetype = []
8987

9088
# 프로그램 인자값, 출력 파일명
91-
argv, filename = util.disting_args(sys.argv[1:], '--year-all', '--csv', '--db')
89+
argv, filename = util.disting_args(sys.argv[1:], '--year-all', '--csv', '--db', '--max-thread')
9290

9391
# 프로그램 환경 식별
9492
# 쓰레드 갯수 식별
95-
thread_count = int(util.define_argument_value(argv, "-thread-count", 4, flag="-tc"))
93+
tcount = util.define_argument_value(argv, "-thread-count", flag="-tc")
9694

9795
# RAW 파일 경로 여부
9896
file_path = util.define_argument_value(argv, "-file", None)
9997

10098

10199
# 구성 인자값 식별
102-
all_years = util.define_argument_value(argv, "--all-year", False)
100+
all_years = util.define_argument_value(argv, "--year-all", False)
103101
all_source = util.define_argument_value(argv, "--all", False)
104102
csv_output = util.define_argument_value(argv, "--csv", False)
105103
sql_output = util.define_argument_value(argv, "--db", False)
104+
max_threaded = util.define_argument_value(argv, "--max-thread", False)
106105

107106
# 계정 인자값 식별
108107
user = util.define_argument_value(argv, "-user", flag="-u")
@@ -115,6 +114,22 @@ def help(error=None):
115114
database_name = util.define_argument_value(argv, "-dbname", flag="-d")
116115
table_name = util.define_argument_value(argv, "-tablename", flag="-t")
117116

117+
if tcount is None:
118+
if max_threaded:
119+
count = os.cpu_count()
120+
print("경고: 사용 가능한 모든 쓰레드를 사용합니다.")
121+
else:
122+
count = 4
123+
124+
if count < 1:
125+
count = 1
126+
tcount = count
127+
else:
128+
tcount = int(tcount)
129+
if max_threaded:
130+
print("경고: 쓰레드 수가 이미 결정되었습니다. MAX-THREAD 인자는 무시됩니다.")
131+
132+
print("THREAD_MOUNT=%d" % tcount)
118133

119134
# 압축 파일 생성 여부
120135
zip_file = False
@@ -271,7 +286,7 @@ def help(error=None):
271286
# 연도 별로 CVE 데이터베이스 작업을 설정해주고 수행합니다.
272287
if year_based_task:
273288
for year in list_year:
274-
export_filepath.append(configure_task(base, table_name, year, filename, file_path))
289+
export_filepath.append(configure_task(base, table_name, year, filename, file_path, thread_count=tcount))
275290

276291
if len(base.execption_list) != 0:
277292
log_filename = "err-{time}.log".format(time=datetime.now()).replace(" ", "").replace(":", ".")
@@ -287,7 +302,7 @@ def help(error=None):
287302
print("\n경고: {count} elements could not be inserted into the table. See {f} for more reasons.\n".format(count=len(base.execption_list), f=log_filename))
288303
base.execption_list.clear()
289304
else:
290-
export_filepath.append(configure_task(base, table_name, None, filename, file_path))
305+
export_filepath.append(configure_task(base, table_name, None, filename, file_path, thread_count=tcount))
291306

292307
# 출력 파일로 만들어져야 할 것이 있습니까?
293308
if len(output_filetype) != 0:

database.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def export(self, export_path_name="unspecified", export_type='sql', tablename="U
197197
password_exist = "-p{pwd}".format(pwd=self.password)
198198
else:
199199
password_exist = ""
200-
ps = subprocess.Popen("mysqldump -u {user} {pwd} -h {host} {database_name} > {output}".format(pwd=password_exist, user=self.user,host=self.host, database_name=self.database,output=filename), shell=True)
200+
ps = subprocess.Popen("mysqldump --column-statistics=0 -u {user} {pwd} -h {host} {database_name} > {output}".format(pwd=password_exist, user=self.user,host=self.host, database_name=self.database,output=filename), shell=True)
201201
ps.communicate()
202202
if ps.returncode == 0:
203203
print("Sucessfully make the export file: %s" % filename)

0 commit comments

Comments
 (0)