diff --git a/Dockerfile_selenium b/Dockerfile_selenium
index d9b03e09..71d15426 100644
--- a/Dockerfile_selenium
+++ b/Dockerfile_selenium
@@ -14,4 +14,4 @@ COPY tests/requirements.txt tests/requirements.txt
RUN pip install -r tests/requirements.txt
COPY tests ./tests
-ENTRYPOINT python3 tests/main.py --login ${LOGIN} --password ${PASSWORD}
+ENTRYPOINT sleep 30 && python3 tests/main.py --login ${LOGIN} --password ${PASSWORD}
diff --git a/app/main/checks/presentation_checks/name_of_image_check.py b/app/main/checks/presentation_checks/name_of_image_check.py
index faffdf17..e95bdc8e 100644
--- a/app/main/checks/presentation_checks/name_of_image_check.py
+++ b/app/main/checks/presentation_checks/name_of_image_check.py
@@ -12,7 +12,8 @@ def __init__(self, file_info):
def check(self):
slides_without_capture = set()
slide_with_image_only = set()
- result_str = 'Не пройдена! '
+ result_str = ''
+ result = True
all_captions = []
for num, slide in enumerate(self.file.slides, 1):
captions = slide.get_captions()
@@ -27,6 +28,7 @@ def check(self):
if caption[0] != slide.get_title():
slide_with_image_only.add(num)
if slides_without_capture:
+ result = False
result_str += (
'Подписи к рисункам на следующих слайдах отсутствуют или не содержат слова "Рисунок": {}'.format(
', '.join(self.format_page_link(sorted(slides_without_capture)))) + ' ')
@@ -34,7 +36,7 @@ def check(self):
result_str += (
'Подписи к рисункам на следующих слайдах без текста необязательны: {}'.format(
', '.join(self.format_page_link(sorted(slide_with_image_only)))) + ' ')
- if result_str:
- return answer(False, name_of_image_check_results(result_str, all_captions))
+ if result:
+ return answer(True, f'Пройдена! {result_str}')
else:
- return answer(True, 'Пройдена!')
+ return answer(False, name_of_image_check_results(f"Не пройдена! {result_str}", all_captions))
diff --git a/app/main/checks/report_checks/__init__.py b/app/main/checks/report_checks/__init__.py
index 0ed2a8dc..30f22617 100644
--- a/app/main/checks/report_checks/__init__.py
+++ b/app/main/checks/report_checks/__init__.py
@@ -32,3 +32,5 @@
from .sw_section_size import SWSectionSizeCheck
from .sw_keywords_check import SWKeywordsCheck
from .task_tracker import ReportTaskTracker
+from .paragraphs_count_check import ReportParagraphsCountCheck
+from .template_name import ReportTemplateNameCheck
diff --git a/app/main/checks/report_checks/literature_references.py b/app/main/checks/report_checks/literature_references.py
index 65205cc3..bcd89792 100644
--- a/app/main/checks/report_checks/literature_references.py
+++ b/app/main/checks/report_checks/literature_references.py
@@ -56,9 +56,7 @@ def check(self):
return answer(False,
f'В Списке использованных источников не найдено ни одного источника.
Проверьте корректность использования нумированного списка.')
references, ref_sequence = self.search_references(start_literature_par)
- all_numbers = set()
- for i in range(1, number_of_sources + 1):
- all_numbers.add(i)
+ all_numbers = set(range(1, number_of_sources + 1))
if len(references.symmetric_difference(all_numbers)) == 0:
if not self.min_ref <= number_of_sources <= self.max_ref:
return answer(False, f'Список источников оформлен верно, однако их количество ({number_of_sources}) не удовлетворяет необходимому критерию. Количество источников должно быть не менее {self.min_ref}.')
@@ -81,7 +79,7 @@ def check(self):
result_str += '''
Если возникли проблемы, попробуйте сделать следующее:
-
Убедитесь, что для ссылки на источник используются квадратные скобки;
+
Убедитесь, что для ссылки на источник используются квадратные скобки (т.е. [1], [2-4]);
Убедитесь, что для оформления списка литературы был использован нумированный список;
Убедитесь, что после и перед нумированным списком отсутствуют непустые абзацы.
Убедитесь, что один источник не разбит на две строки клавишей "Enter".
@@ -93,13 +91,16 @@ def search_references(self, start_par):
prev_ref = 0
ref_sequence = []
array_of_references = set()
+ reg_exp = r'\[[\^]{0,1}[\d \-,]+\]' # md can use [^5] format for hyperlink
for i in range(0, start_par):
if isinstance(self.file.paragraphs[i], str):
- detected_references = re.findall(r'\[[\d \-,]+\]', self.file.paragraphs[i])
+ detected_references = re.findall(reg_exp, self.file.paragraphs[i])
else:
- detected_references = re.findall(r'\[[\d \-,]+\]', self.file.paragraphs[i].paragraph_text)
+ detected_references = re.findall(reg_exp, self.file.paragraphs[i].paragraph_text)
+
if detected_references:
- for reference in detected_references:
+ for reference_raw in detected_references:
+ reference = reference_raw.replace('^', '') # TODO: kostyl'...
for one_part in re.split(r'[\[\],]', reference):
if re.match(r'\d+[ \-]+\d+', one_part):
start, end = re.split(r'[ -]+', one_part)
diff --git a/app/main/checks/report_checks/main_character_check.py b/app/main/checks/report_checks/main_character_check.py
index 723fb536..c596e999 100644
--- a/app/main/checks/report_checks/main_character_check.py
+++ b/app/main/checks/report_checks/main_character_check.py
@@ -1,48 +1,114 @@
from ..base_check import BaseReportCriterion, answer
+from .main_page_settings import ReportMainPageSetting
+import re
+import copy
class ReportMainCharacterCheck(BaseReportCriterion):
- label = "Проверка фамилии и должности заведующего кафедрой"
- description = 'Зав. кафедрой: А.А. Лисс'
- id = 'main_character_check'
+ label = "Проверка составляющих титульного листа, задания и календарного плана"
+ description = ""
+ id = "main_character_check"
priority = True
- def __init__(self, file_info, main_character_name_right="А.А. Лисс", main_character_name_wrong="К.В. Кринкин",
- main_character_job_right="Зав. кафедрой", main_character_job_wrong="И.о. зав. кафедрой"):
+ def __init__(self, file_info, tables_count_to_verify=8):
super().__init__(file_info)
self.headers = []
- self.main_character_name_right = main_character_name_right
- self.main_character_name_wrong = main_character_name_wrong
- self.main_character_job_right = main_character_job_right
- self.main_character_job_wrong = main_character_job_wrong
+ self.first_check_list = None
+ self.second_check_list = None
+ self.tables_count_to_verify = tables_count_to_verify
def late_init(self):
- self.headers = self.file.make_headers(self.file_type['report_type'])
+ self.headers = self.file.make_headers(self.file_type["report_type"])
def check(self):
+ self.first_check_list = copy.deepcopy(ReportMainPageSetting.FIRST_TABLE)
+ self.second_check_list = copy.deepcopy(ReportMainPageSetting.SECOND_TABLE)
if self.file.page_counter() < 4:
return answer(False, "В отчете недостаточно страниц. Нечего проверять.")
+ if self.tables_count_to_verify > len(self.file.tables):
+ return answer(
+ False,
+ f"Количество таблиц на страницах титульного листа, задания и календарного плана должно быть не меньше {self.tables_count_to_verify}",
+ )
self.late_init()
- result_str = ''
+ result_str = ""
+ pages = []
for header in self.headers:
if header["marker"] and header["main_character"]:
- page = header["page"]
- text_on_page = self.file.pdf_file.text_on_page[page]
- if text_on_page.find(self.main_character_name_wrong) >= 0 and not text_on_page.find(
- self.main_character_name_right) >= 0:
- result_str += f"На странице {self.format_page_link([page])} указана неверная фамилия заведующего " \
- f"кафедрой. Убедитесь, что {self.main_character_job_right} {self.main_character_name_right}. "
- elif not text_on_page.find(self.main_character_name_right) >= 0:
- result_str += f"На странице {self.format_page_link([page])} не указано ФИО заведующего кафедрой, в " \
- f"графе {self.main_character_job_right} должно быть указано {self.main_character_name_right}. "
- if text_on_page.find(self.main_character_job_wrong) >= 0 and not text_on_page.find(
- self.main_character_job_right) >= 0:
- result_str += f'На странице {self.format_page_link([page])} указана неверная должность ' \
- f'заведующего кафедрой, должно быть "{self.main_character_job_right}". '
- if not result_str:
- return answer(True, 'ФИО и должность исполняющего обязанности зав. кафедрой указаны верно на всех листах.')
+ pages.append(header["page"])
+ for i in range(self.tables_count_to_verify):
+ table = self.file.tables[i]
+ extract_table = self.extract_table_contents(table)
+ self.check_table(self.first_check_list, extract_table, i+1)
+ self.check_table(self.second_check_list, extract_table, i+1)
+ links = self.format_page_link(pages)
+ result_score = 1.0
+ check_result = self.first_check_list + self.second_check_list
+ penalty_score = 1 / len(check_result)
+ for res in check_result:
+ if res["found_key"] > 1 and res["key"] == "Консультант":
+ links = self.format_page_link(pages[1:])
+ result_str += f"Предупреждение: помните, что на страницах {links} указывается только консультант, являющийся фактическим руководителем (консультант от кафедры / по допразделу не указываются). "
+ elif res["found_key"] < res["find"] and res["key"] != "Консультант":
+ result_score -= penalty_score * (res["find"] - res['found_value'])
+ result_str += f"Поле '{res['key']}' не найдено на страницах {links}. Его удалось обнаружить {res['found_key']} из {res['find']} раз. Проверьте корректность всех вхождений. "
+ elif res["found_value"] < res["find"]:
+ result_score -= penalty_score * (res["find"] - res['found_value'])
+ links = self.format_page_link(pages)
+ result_str += f"Содержимое поля '{res['key']}' указано корректно {res['found_value']} из {res['find']} раз. Проверьте корректность всех вхождений на страницах {links}. "
+ result_str += f""" Логи проверки: {" ".join(res['logs'] for res in check_result)} """
+ if result_score < 0:
+ result_score = 0 # for case with big penalty
+
+ if result_score == 1.0:
+ return answer(result_score, f"Пройдена! {result_str}")
else:
- result_str += f' Убедитесь, что вы использовали правильные формы бланков титульного листа, задания и календарного плана.' \
- f' Для бакалавров: Формы бланков для бакалавров.' \
- f' Для магистров: Формы бланков для магистров.'
- return answer(False, result_str)
+ result_str += (
+ f" Убедитесь, что вы использовали правильные формы бланков титульного листа, задания и календарного плана."
+ f' Для бакалавров: Формы бланков для бакалавров.'
+ f' Для магистров: Формы бланков для магистров.'
+ )
+ return answer(result_score, result_str)
+
+ def extract_table_contents(self, table):
+ contents = []
+ processed_cells = set()
+ for row in table.rows:
+ row_text = []
+ for cell in row.cells:
+ if cell not in processed_cells:
+ row_text.append(cell.text.strip())
+ processed_cells.add(cell)
+ contents.append("|".join(row_text))
+ return contents
+
+ def calculate_find_value(self, table, index):
+ count = int((len(table) - index - 2) / 2)
+ if count >= 0:
+ return count
+ return 0
+
+ def check_table(self, check_list, table, table_num):
+ for item in check_list:
+ for i, line in enumerate(table):
+ if item["key"] in line:
+ item["found_key"] += 1
+ item["logs"] += f"'{item['key']}': ключ компоненты найден в строке '{line}' в таблице №{table_num} "
+
+ for value in item["value"]:
+ if re.search(value, line):
+ item["found_value"] += 1
+ item["logs"] += f"\t'{item['key']}': значение компоненты '{value}' найдено в строке '{line}' в таблице №{table_num} "
+ break
+
+ if item["key"] != "Зав. кафедрой" and item["key"] != "Консультант":
+ continue
+
+ elif item["key"] in ["Зав. кафедрой", "Консультант"] and item["found_key"] > 0:
+ if item["key"] == "Консультант":
+ if item["found_key"] == 1:
+ item["find"] += self.calculate_find_value(table, i)
+ for value in item["value"]:
+ if re.search(value, line):
+ item["found_value"] += 1
+ item["logs"] += f"'{item['key']}': значение компоненты '{value}' найдено в строке '{line}' в таблице №{table_num} "
diff --git a/app/main/checks/report_checks/main_page_settings.py b/app/main/checks/report_checks/main_page_settings.py
new file mode 100644
index 00000000..6122aeca
--- /dev/null
+++ b/app/main/checks/report_checks/main_page_settings.py
@@ -0,0 +1,69 @@
+class ReportMainPageSetting:
+ FIRST_TABLE = [
+ {
+ "key": "Направление",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 1,
+ "value": [
+ "01.03.02 Прикладная математика и информатика",
+ "09.03.04 Программная инженерия",
+ ],
+ "logs": ""
+ },
+ {
+ "key": "Профиль",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 1,
+ "value": [
+ "Математическое обеспечение программно-информационных систем",
+ "Разработка программно-информационных систем"
+ ],
+ "logs": ""
+ },
+ {
+ "key": "Факультет",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 1,
+ "value": ["КТИ"],
+ "logs": ""
+ },
+ {
+ "key": "Кафедра",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 1,
+ "value": ["МО ЭВМ"],
+ "logs": ""
+ },
+ {
+ "key": "Зав. кафедрой",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 3,
+ "value": ["А.А. Лисс"],
+ "logs": ""
+ }
+ ]
+
+ SECOND_TABLE = [
+ {
+ "key": "Руководитель",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 3,
+ "value": [r"(Руководитель).*([кд]\..+\.н\., (доцент|профессор))[|]*([А-Я]\.[А-Я]\. [А-Я][а-я]+)"], #
+ "logs": ""
+ },
+ {
+ "key": "Консультант",
+ "found_value": 0,
+ "found_key": 0,
+ "find": 1,
+ "value": [r"[кд]\..+\.н\., (доцент|профессор)"], # (Консультант).*(([кд]\..+\.н\., (доцент|профессор))|).*([А-Я]\.[А-Я]\. [А-Я][а-я]+)
+ # (([кд]\..+\.н\., (доцент|профессор))|)[|]*([А-Я]\.[А-Я]\. [А-Я][а-я]+)
+ "logs": ""
+ }
+ ]
\ No newline at end of file
diff --git a/app/main/checks/report_checks/paragraphs_count_check.py b/app/main/checks/report_checks/paragraphs_count_check.py
new file mode 100644
index 00000000..b8c68ce4
--- /dev/null
+++ b/app/main/checks/report_checks/paragraphs_count_check.py
@@ -0,0 +1,120 @@
+import re
+from .style_check_settings import StyleCheckSettings
+from ..base_check import BaseReportCriterion, answer
+
+class ReportParagraphsCountCheck(BaseReportCriterion):
+ label = "Проверка количества абзацев в главах и их подразделах"
+ description = ""
+ id = "paragraphs_count_check"
+
+ def __init__(self, file_info, min_paragraphs_in_unnumbered_section=2, min_paragraphs_in_section=5,
+ min_paragraphs_in_subsection=5, min_paragraphs_in_subsubsection=1, skip_sections=None):
+ super().__init__(file_info)
+ self.min_count_paragraphs = {
+ "unnumbered_section": min_paragraphs_in_unnumbered_section,
+ "section": min_paragraphs_in_section,
+ "subsection": min_paragraphs_in_subsection,
+ "subsubsection": min_paragraphs_in_subsubsection
+ }
+ self.heading_styles = {style: value["docx_style"] for style, value in StyleCheckSettings.VKR_CONFIG.items()}
+ self.paragraphs_count = []
+ self.headers = []
+ self.skip_sections = skip_sections if skip_sections else list()
+
+ def late_init(self):
+ self.headers = self.file.make_chapters(self.file_type['report_type'])
+
+ def check(self):
+ if self.file.page_counter() < 4:
+ return answer(False, "В отчете недостаточно страниц. Нечего проверять.")
+
+ self.late_init()
+ result = True
+ result_str = ""
+
+ if not self.headers:
+ return answer(False, "Не найдено ни одного заголовка.
Проверьте корректность использования стилей.")
+
+ self.find_paragraphs_count()
+
+ for obj in self.paragraphs_count:
+ if obj["paragraphs"] < obj["min"]:
+ result = False
+ result_str += (f'Раздел "{obj["name"]}" содержит {obj["paragraphs"]} абзацев '
+ f'(не считая рисунки и таблицы), что меньше минимальной рекомендуемой '
+ f'длины раздела в {obj["min"]} абзацев. ')
+ return answer(result, result_str if result_str else "Пройдена!")
+
+ def find_paragraphs_count(self):
+ i = 0
+ while i < len(self.headers):
+ for skip_section in self.skip_sections:
+ if skip_section.lower() in self.headers[i]["text"].lower():
+ i+=1
+ continue
+
+ if "ПРИЛОЖЕНИЕ" in self.headers[i]["text"]:
+ break
+
+ if self.headers[i]["style"] == self.heading_styles['any_header'][0] and not re.search(r'\d', self.headers[i]["text"]):
+ count_lists_section, ignored_paragraphs = self.find_lists_and_captions(self.headers[i]["child"])
+ self.paragraphs_count.append({
+ "name": self.headers[i]["text"],
+ "min": self.min_count_paragraphs["unnumbered_section"],
+ "paragraphs": len(self.headers[i]["child"]) - ignored_paragraphs + count_lists_section,
+ "lists": count_lists_section
+ })
+
+ elif self.headers[i]["style"] == self.heading_styles['second_header'][0]:
+ count_lists_section, ignored_paragraphs = self.find_lists_and_captions(self.headers[i]["child"])
+ section_count = len(self.headers[i]["child"]) - ignored_paragraphs + count_lists_section
+
+ j = i + 1
+ while j < len(self.headers) and self.headers[j]["style"] == self.heading_styles['second_header'][1]:
+ count_lists_subsection, ignored_paragraphs = self.find_lists_and_captions(self.headers[j]["child"])
+ subsection_count = len(self.headers[j]["child"]) - ignored_paragraphs + count_lists_subsection
+
+ k = j + 1
+ while k < len(self.headers) and self.headers[k]["style"] == self.heading_styles['second_header'][2]:
+ count_lists_subsubsection, ignored_paragraphs = self.find_lists_and_captions(self.headers[k]["child"])
+ subsubsection_count = len(self.headers[k]["child"]) - ignored_paragraphs + count_lists_subsubsection
+ subsection_count += subsubsection_count
+ count_lists_subsection += count_lists_subsubsection
+
+ self.paragraphs_count.append({
+ "name": self.headers[k]["text"],
+ "min": self.min_count_paragraphs["subsubsection"],
+ "paragraphs": subsubsection_count,
+ "lists": count_lists_subsubsection
+ })
+ k += 1
+
+ section_count += subsection_count
+ count_lists_section += count_lists_subsection
+
+ self.paragraphs_count.append({
+ "name": self.headers[j]["text"],
+ "min": self.min_count_paragraphs["subsection"],
+ "paragraphs": subsection_count,
+ "lists": count_lists_subsection
+ })
+ j = k
+
+ self.paragraphs_count.append({
+ "name": self.headers[i]["text"],
+ "min": self.min_count_paragraphs["section"],
+ "paragraphs": section_count,
+ "lists": count_lists_section
+ })
+ i = j - 1
+
+ i += 1
+
+ def find_lists_and_captions(self, paragraphs):
+ ignored_paragraphs = 0
+ count_lists = 0
+ for paragraph in paragraphs:
+ if paragraph["style"].find("вкр_подпись") != -1:
+ ignored_paragraphs += 1
+ # necessary search lists
+ return count_lists, ignored_paragraphs
diff --git a/app/main/checks/report_checks/section_component.py b/app/main/checks/report_checks/section_component.py
index 1e39bdaa..7641d150 100644
--- a/app/main/checks/report_checks/section_component.py
+++ b/app/main/checks/report_checks/section_component.py
@@ -58,4 +58,4 @@ def check(self):
return answer(True, f'Все необходимые компоненты раздела "{self.chapter}" обнаружены!')
else:
return answer(False,
- f'Не найдены следующие компоненты раздела {self.chapter}:
{result_str}
')
+ f'Не найдены следующие компоненты раздела {self.chapter} (обратите внимание на требования к разделу и его составляющим):
{result_str}
')
diff --git a/app/main/checks/report_checks/style_check_settings.py b/app/main/checks/report_checks/style_check_settings.py
index 082bf4b8..7c3a61b5 100644
--- a/app/main/checks/report_checks/style_check_settings.py
+++ b/app/main/checks/report_checks/style_check_settings.py
@@ -17,7 +17,7 @@ class StyleCheckSettings:
'тестить', 'тул', 'тула', 'тулза', 'фиксить', 'флажок', 'флаг', 'юзкейс', 'продакт', 'продакшн',
'прод', 'фидбек', 'дедлайн', 'дэдлайн', 'оптимально', 'оптимальный', 'надежный', 'интуитивный',
'хороший', 'плохой', 'идеальный', 'быстро', 'медленно', 'какой-нибудь', 'некоторый', 'почти'
- ]
+ ] # TODO: list of "warning" words
STD_MIN_LIT_REF = 1
STD_MAX_LIT_REF = 1000 #just in case for future edit
HEADER_1_STYLE = {
@@ -133,22 +133,36 @@ class StyleCheckSettings:
'second_header':
{
"style": HEADER_1_NUM_STYLE,
- "docx_style": ["heading 2", "heading 3", "heading 4"],
+ "docx_style": ["heading 2", "heading 3", "heading 4"], # TODO: rm 'heading 2'?
"headers": [],
"unify_regex": None,
"regex": HEADER_NUM_REGEX,
}
}
-
+
+ NIR1_CONFIG = {
+ 'any_header':
+ {
+ "style": HEADER_1_STYLE,
+ "docx_style": ["heading 2"],
+ "headers": ["ВВЕДЕНИЕ", "ПОСТАНОВКА ЗАДАЧИ", "ОБЗОР ЛИТЕРАТУРЫ", "ВЫВОДЫ",
+ "ПЛАН РАБОТЫ НА ВЕСЕННИЙ СЕМЕСТР", "ОТЗЫВ РУКОВОДИТЕЛЯ", "СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ"],
+ "unify_regex": None,
+ "regex": HEADER_REGEX,
+ "banned_words": STD_BANNED_WORDS + ['доработать', 'доработка', 'переписать', 'рефакторинг', 'исправление']
+ },
+ }
+
NIR2_CONFIG = {
'any_header':
{
"style": HEADER_1_STYLE,
"docx_style": ["heading 2"],
- "headers": ["ПОСТАНОВКА ЗАДАЧИ", "РЕЗУЛЬТАТЫ РАБОТЫ В ВЕСЕННЕМ СЕМЕСТРЕ", "ОПИСАНИЕ ПРЕДПОЛАГАЕМОГО МЕТОДА РЕШЕНИЯ",
+ "headers": ["ВВЕДЕНИЕ", "ПОСТАНОВКА ЗАДАЧИ", "РЕЗУЛЬТАТЫ РАБОТЫ В ВЕСЕННЕМ СЕМЕСТРЕ", "ОПИСАНИЕ ПРЕДПОЛАГАЕМОГО МЕТОДА РЕШЕНИЯ",
"ПЛАН РАБОТЫ НА ОСЕННИЙ СЕМЕСТР", "СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ"],
"unify_regex": None,
"regex": HEADER_REGEX,
+ "banned_words": STD_BANNED_WORDS + ['доработать', 'доработка', 'переписать', 'рефакторинг', 'исправление']
},
}
@@ -157,8 +171,8 @@ class StyleCheckSettings:
{
"style": HEADER_1_STYLE,
"docx_style": ["heading 2"],
- "headers": ["ПОСТАНОВКА ЗАДАЧИ", "РЕЗУЛЬТАТЫ РАБОТЫ В ОСЕННЕМ СЕМЕСТРЕ", "ОПИСАНИЕ ПРЕДПОЛАГАЕМОГО МЕТОДА РЕШЕНИЯ",
- "ПЛАН РАБОТЫ НА ВЕСЕННИЙ СЕМЕСТР", "СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ"],
+ "headers": ["ВВЕДЕНИЕ", "ПОСТАНОВКА ЗАДАЧИ", "РЕЗУЛЬТАТЫ РАБОТЫ В ОСЕННЕМ СЕМЕСТРЕ", "ОПИСАНИЕ ПРЕДПОЛАГАЕМОГО МЕТОДА РЕШЕНИЯ",
+ "ПЛАН РАБОТЫ НА ВЕСЕННИЙ СЕМЕСТР", "ОТЗЫВ РУКОВОДИТЕЛЯ", "СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ"],
"unify_regex": None,
"regex": HEADER_REGEX,
"banned_words": STD_BANNED_WORDS + ['доработать', 'доработка', 'переписать', 'рефакторинг', 'исправление']
@@ -208,7 +222,8 @@ class StyleCheckSettings:
"Актуальность",
"Объект исследования",
"Предмет исследования",
- "Цель",
+ "Цель дипломного исследования",
+ "Цель на текущий семестр",
"Задачи",
"Список использованных источников"
],
@@ -306,6 +321,7 @@ class StyleCheckSettings:
'VKR_HEADERS': VKR_CONFIG,
'VKR_MAIN_TEXT': VKR_MAIN_TEXT_CONFIG,
'NIR_HEADERS': NIR2_CONFIG,
+ 'NIR1_HEADERS': NIR1_CONFIG,
'NIR2_HEADERS': NIR2_CONFIG,
'NIR3_HEADERS': NIR3_CONFIG,
'MD_HEADERS' : MD_CONFIG,
diff --git a/app/main/checks/report_checks/sw_section_size.py b/app/main/checks/report_checks/sw_section_size.py
index dbb9a6f0..42d9330e 100644
--- a/app/main/checks/report_checks/sw_section_size.py
+++ b/app/main/checks/report_checks/sw_section_size.py
@@ -18,7 +18,11 @@
"words": 15,
"sentences": 1
},
- "Цель": {
+ "Цель дипломного исследования": {
+ "words": 30,
+ "sentences": 1
+ },
+ "Цель на текущий семестр": {
"words": 30,
"sentences": 1
}
@@ -59,11 +63,11 @@ def check(self):
}
feedback = ""
if not all(r['sentences'] for r in result.values()):
- feedback += " Размер следующих разделов не удовлетворяет требованиям по количеству предложений (помните, что часть разделов явлются словосочетаниями, а не полным текстом): - " + \
- ' - '.join(f"'{chapter}' - должен быть не более {self.sections[chapter]['sentences']}" for chapter, check in result.items() if not check['sentences'])
+ feedback += " Размер следующих разделов не удовлетворяет требованиям по количеству предложений (считается по знаку препинания 'точка') - помните, что часть разделов явлются словосочетаниями, а не полным текстом: - " + \
+ ' - '.join(f"'{chapter}' - должен быть не более {self.sections[chapter]['sentences']}" for chapter, check in result.items() if check and not check['sentences'])
if not all(r['words'] for r in result.values()):
feedback += " Размер следующих разделов не удовлетворяет требованиям по количеству слов (попробуйте подобрать более ёмкие и короткие формулировки): - " + \
- ' - '.join(f"'{chapter}' - должен быть не более {self.sections[chapter]['words']}" for chapter, check in result.items() if not check['words'])
+ ' - '.join(f"'{chapter}' - должен быть не более {self.sections[chapter]['words']}" for chapter, check in result.items() if check and not check['words'])
if feedback:
return answer(0, feedback)
diff --git a/app/main/presentations/pptx/slide_pptx.py b/app/main/presentations/pptx/slide_pptx.py
index e71dff7f..d5b69074 100644
--- a/app/main/presentations/pptx/slide_pptx.py
+++ b/app/main/presentations/pptx/slide_pptx.py
@@ -18,7 +18,7 @@ def __init__(self, container, w, h, index=-1):
else:
try:
self.page_number = [int(p.text), int(p.left), int(p.top)]
- except ValueError:
+ except (ValueError, TypeError) as exc:
self.page_number = [-1, -1, -1]
if container.shapes.title:
self.title = container.shapes.title.text
diff --git a/app/main/reports/md_uploader/md_uploader.py b/app/main/reports/md_uploader/md_uploader.py
index ebb7d155..da48f32c 100644
--- a/app/main/reports/md_uploader/md_uploader.py
+++ b/app/main/reports/md_uploader/md_uploader.py
@@ -108,6 +108,8 @@ def parse_effective_styles(self):
for par in self.paragraphs:
if len(par.strip()) > 0:
paragraph = {"text": par, "runs": []}
+ if '
' in paragraph["text"]:
+ paragraph["runs"].append({"text": par, "style": "heading 1"})
if '
' in paragraph["text"]:
paragraph["runs"].append({"text": par, "style": "heading 2"})
elif '