annofabcli 1.102.1__py3-none-any.whl → 1.104.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- annofabcli/__main__.py +1 -1
- annofabcli/annotation/annotation_query.py +9 -29
- annofabcli/annotation/change_annotation_attributes.py +6 -14
- annofabcli/annotation/change_annotation_properties.py +5 -12
- annofabcli/annotation/copy_annotation.py +4 -10
- annofabcli/annotation/delete_annotation.py +10 -26
- annofabcli/annotation/dump_annotation.py +1 -4
- annofabcli/annotation/import_annotation.py +15 -39
- annofabcli/annotation/list_annotation.py +1 -4
- annofabcli/annotation/merge_segmentation.py +5 -15
- annofabcli/annotation/remove_segmentation_overlap.py +8 -29
- annofabcli/annotation/restore_annotation.py +3 -9
- annofabcli/annotation_specs/add_attribute_restriction.py +2 -8
- annofabcli/annotation_specs/attribute_restriction.py +2 -10
- annofabcli/annotation_specs/export_annotation_specs.py +1 -3
- annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -10
- annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +4 -10
- annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +1 -3
- annofabcli/annotation_specs/list_annotation_specs_attribute.py +7 -18
- annofabcli/annotation_specs/list_annotation_specs_choice.py +3 -8
- annofabcli/annotation_specs/list_annotation_specs_history.py +0 -1
- annofabcli/annotation_specs/list_annotation_specs_label.py +3 -8
- annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +4 -9
- annofabcli/annotation_specs/list_attribute_restriction.py +3 -9
- annofabcli/annotation_specs/put_label_color.py +1 -6
- annofabcli/comment/delete_comment.py +3 -9
- annofabcli/comment/list_all_comment.py +15 -5
- annofabcli/comment/list_comment.py +46 -7
- annofabcli/comment/put_comment.py +4 -13
- annofabcli/comment/put_comment_simply.py +2 -6
- annofabcli/comment/put_inspection_comment.py +2 -6
- annofabcli/comment/put_inspection_comment_simply.py +3 -6
- annofabcli/comment/put_onhold_comment.py +2 -6
- annofabcli/comment/put_onhold_comment_simply.py +2 -4
- annofabcli/common/cli.py +5 -43
- annofabcli/common/download.py +8 -25
- annofabcli/common/image.py +3 -7
- annofabcli/common/utils.py +2 -4
- annofabcli/common/visualize.py +2 -4
- annofabcli/filesystem/draw_annotation.py +6 -18
- annofabcli/filesystem/filter_annotation.py +7 -24
- annofabcli/filesystem/mask_user_info.py +2 -5
- annofabcli/filesystem/merge_annotation.py +2 -6
- annofabcli/input_data/change_input_data_name.py +3 -7
- annofabcli/input_data/copy_input_data.py +6 -14
- annofabcli/input_data/delete_input_data.py +7 -24
- annofabcli/input_data/delete_metadata_key_of_input_data.py +5 -16
- annofabcli/input_data/list_all_input_data.py +5 -14
- annofabcli/input_data/list_all_input_data_merged_task.py +8 -23
- annofabcli/input_data/list_input_data.py +5 -16
- annofabcli/input_data/put_input_data.py +7 -19
- annofabcli/input_data/update_metadata_of_input_data.py +6 -14
- annofabcli/instruction/list_instruction_history.py +0 -1
- annofabcli/instruction/upload_instruction.py +4 -7
- annofabcli/job/list_job.py +2 -3
- annofabcli/job/list_last_job.py +1 -3
- annofabcli/organization/list_organization.py +0 -1
- annofabcli/organization_member/change_organization_member.py +1 -3
- annofabcli/organization_member/delete_organization_member.py +2 -6
- annofabcli/organization_member/invite_organization_member.py +1 -3
- annofabcli/organization_member/list_organization_member.py +0 -1
- annofabcli/project/change_organization_of_project.py +257 -0
- annofabcli/project/change_project_status.py +2 -2
- annofabcli/project/copy_project.py +2 -7
- annofabcli/project/diff_projects.py +4 -16
- annofabcli/project/list_project.py +0 -1
- annofabcli/project/put_project.py +2 -6
- annofabcli/project/subcommand_project.py +2 -0
- annofabcli/project_member/change_project_members.py +1 -1
- annofabcli/project_member/copy_project_members.py +2 -7
- annofabcli/project_member/drop_project_members.py +1 -3
- annofabcli/project_member/invite_project_members.py +2 -4
- annofabcli/project_member/list_users.py +0 -1
- annofabcli/project_member/put_project_members.py +4 -12
- annofabcli/stat_visualization/mask_visualization_dir.py +6 -16
- annofabcli/stat_visualization/merge_visualization_dir.py +7 -19
- annofabcli/stat_visualization/summarize_whole_performance_csv.py +3 -7
- annofabcli/stat_visualization/write_graph.py +5 -15
- annofabcli/stat_visualization/write_performance_rating_csv.py +4 -12
- annofabcli/statistics/list_annotation_area.py +3 -7
- annofabcli/statistics/list_annotation_attribute.py +6 -15
- annofabcli/statistics/list_annotation_attribute_filled_count.py +9 -23
- annofabcli/statistics/list_annotation_count.py +18 -44
- annofabcli/statistics/list_annotation_duration.py +14 -40
- annofabcli/statistics/list_video_duration.py +2 -3
- annofabcli/statistics/list_worktime.py +0 -1
- annofabcli/statistics/scatter.py +3 -9
- annofabcli/statistics/summarize_task_count.py +7 -12
- annofabcli/statistics/summarize_task_count_by_task_id_group.py +3 -11
- annofabcli/statistics/summarize_task_count_by_user.py +1 -5
- annofabcli/statistics/visualization/dataframe/annotation_count.py +2 -4
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +6 -12
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py +10 -22
- annofabcli/statistics/visualization/dataframe/project_performance.py +1 -3
- annofabcli/statistics/visualization/dataframe/task.py +2 -5
- annofabcli/statistics/visualization/dataframe/task_history.py +1 -1
- annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +6 -20
- annofabcli/statistics/visualization/dataframe/user_performance.py +29 -88
- annofabcli/statistics/visualization/dataframe/whole_performance.py +6 -12
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +17 -49
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py +4 -10
- annofabcli/statistics/visualization/filtering_query.py +2 -6
- annofabcli/statistics/visualization/project_dir.py +9 -26
- annofabcli/statistics/visualization/visualization_source_files.py +3 -10
- annofabcli/statistics/visualize_annotation_count.py +9 -23
- annofabcli/statistics/visualize_annotation_duration.py +5 -15
- annofabcli/statistics/visualize_statistics.py +18 -53
- annofabcli/statistics/visualize_video_duration.py +8 -19
- annofabcli/supplementary/delete_supplementary_data.py +7 -23
- annofabcli/supplementary/list_supplementary_data.py +1 -1
- annofabcli/supplementary/put_supplementary_data.py +5 -15
- annofabcli/task/cancel_acceptance.py +3 -4
- annofabcli/task/change_operator.py +3 -11
- annofabcli/task/change_status_to_break.py +1 -1
- annofabcli/task/change_status_to_on_hold.py +5 -18
- annofabcli/task/complete_tasks.py +8 -25
- annofabcli/task/copy_tasks.py +2 -3
- annofabcli/task/delete_metadata_key_of_task.py +2 -6
- annofabcli/task/delete_tasks.py +8 -26
- annofabcli/task/list_all_tasks.py +2 -4
- annofabcli/task/list_tasks.py +3 -7
- annofabcli/task/list_tasks_added_task_history.py +7 -21
- annofabcli/task/put_tasks.py +2 -3
- annofabcli/task/put_tasks_by_count.py +3 -7
- annofabcli/task/reject_tasks.py +7 -19
- annofabcli/task/update_metadata_of_task.py +2 -2
- annofabcli/task_history/list_all_task_history.py +2 -5
- annofabcli/task_history/list_task_history.py +0 -1
- annofabcli/task_history_event/list_all_task_history_event.py +4 -11
- annofabcli/task_history_event/list_worktime.py +4 -14
- {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/METADATA +1 -1
- annofabcli-1.104.0.dist-info/RECORD +215 -0
- annofabcli-1.102.1.dist-info/RECORD +0 -214
- {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/WHEEL +0 -0
- {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -214,15 +214,9 @@ class WriteCsvGraph:
|
|
|
214
214
|
acceptor_obj = AcceptorCumulativeProductivity.from_df_wrapper(task_worktime_obj)
|
|
215
215
|
|
|
216
216
|
if not self.output_only_text:
|
|
217
|
-
self.project_dir.write_cumulative_line_graph(
|
|
218
|
-
|
|
219
|
-
)
|
|
220
|
-
self.project_dir.write_cumulative_line_graph(
|
|
221
|
-
inspector_obj, phase=TaskPhase.INSPECTION, user_id_list=user_id_list, minimal_output=self.minimal_output
|
|
222
|
-
)
|
|
223
|
-
self.project_dir.write_cumulative_line_graph(
|
|
224
|
-
acceptor_obj, phase=TaskPhase.ACCEPTANCE, user_id_list=user_id_list, minimal_output=self.minimal_output
|
|
225
|
-
)
|
|
217
|
+
self.project_dir.write_cumulative_line_graph(annotator_obj, phase=TaskPhase.ANNOTATION, user_id_list=user_id_list, minimal_output=self.minimal_output)
|
|
218
|
+
self.project_dir.write_cumulative_line_graph(inspector_obj, phase=TaskPhase.INSPECTION, user_id_list=user_id_list, minimal_output=self.minimal_output)
|
|
219
|
+
self.project_dir.write_cumulative_line_graph(acceptor_obj, phase=TaskPhase.ACCEPTANCE, user_id_list=user_id_list, minimal_output=self.minimal_output)
|
|
226
220
|
|
|
227
221
|
def write_worktime_per_date(self, user_id_list: Optional[list[str]] = None) -> None:
|
|
228
222
|
"""日ごとの作業時間情報を出力する。"""
|
|
@@ -231,15 +225,11 @@ class WriteCsvGraph:
|
|
|
231
225
|
self.project_dir.write_worktime_per_date_user(worktime_per_date_obj)
|
|
232
226
|
|
|
233
227
|
task = self._get_task()
|
|
234
|
-
productivity_per_completed_date_obj = WholeProductivityPerCompletedDate.from_df_wrapper(
|
|
235
|
-
task, worktime_per_date_obj, task_completion_criteria=self.task_completion_criteria
|
|
236
|
-
)
|
|
228
|
+
productivity_per_completed_date_obj = WholeProductivityPerCompletedDate.from_df_wrapper(task, worktime_per_date_obj, task_completion_criteria=self.task_completion_criteria)
|
|
237
229
|
|
|
238
230
|
self.project_dir.write_whole_productivity_per_date(productivity_per_completed_date_obj)
|
|
239
231
|
|
|
240
|
-
productivity_per_started_date_obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(
|
|
241
|
-
task, task_completion_criteria=self.task_completion_criteria
|
|
242
|
-
)
|
|
232
|
+
productivity_per_started_date_obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(task, task_completion_criteria=self.task_completion_criteria)
|
|
243
233
|
self.project_dir.write_whole_productivity_per_first_annotation_started_date(productivity_per_started_date_obj)
|
|
244
234
|
|
|
245
235
|
if not self.output_only_text:
|
|
@@ -352,7 +342,7 @@ class VisualizingStatisticsMain:
|
|
|
352
342
|
df_annotation_count = self.annotation_count.df
|
|
353
343
|
df_annotation_count = df_annotation_count[df_annotation_count["project_id"] == project_id]
|
|
354
344
|
# `annotation_count = None`にする理由:後続の処理でアノテーションZIPからアノテーション数を算出するようにするため
|
|
355
|
-
if len(df_annotation_count) == 0:
|
|
345
|
+
if len(df_annotation_count) == 0:
|
|
356
346
|
annotation_count = None
|
|
357
347
|
else:
|
|
358
348
|
annotation_count = AnnotationCount(df_annotation_count)
|
|
@@ -525,12 +515,8 @@ class VisualizeStatistics(CommandLine):
|
|
|
525
515
|
|
|
526
516
|
if len(output_project_dir_list) > 0:
|
|
527
517
|
project_dir_list = [ProjectDir(e, task_completion_criteria) for e in output_project_dir_list]
|
|
528
|
-
custom_production_volume_list =
|
|
529
|
-
|
|
530
|
-
)
|
|
531
|
-
project_performance = ProjectPerformance.from_project_dirs(
|
|
532
|
-
project_dir_list, custom_production_volume_list=custom_production_volume_list
|
|
533
|
-
)
|
|
518
|
+
custom_production_volume_list = custom_production_volume.custom_production_volume_list if custom_production_volume is not None else None
|
|
519
|
+
project_performance = ProjectPerformance.from_project_dirs(project_dir_list, custom_production_volume_list=custom_production_volume_list)
|
|
534
520
|
project_performance.to_csv(root_output_dir / "プロジェクトごとの生産性と品質.csv")
|
|
535
521
|
|
|
536
522
|
project_actual_worktime = ProjectWorktimePerMonth.from_project_dirs(project_dir_list, WorktimeColumn.ACTUAL_WORKTIME_HOUR)
|
|
@@ -571,18 +557,14 @@ class VisualizeStatistics(CommandLine):
|
|
|
571
557
|
else:
|
|
572
558
|
df_actual_worktime = pandas.read_csv(args.labor_csv)
|
|
573
559
|
if not ActualWorktime.required_columns_exist(df_actual_worktime):
|
|
574
|
-
logger.error(
|
|
575
|
-
"引数`--labor_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `date`, `account_id`, `actual_worktime_hour`"
|
|
576
|
-
)
|
|
560
|
+
logger.error("引数`--labor_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `date`, `account_id`, `actual_worktime_hour`")
|
|
577
561
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
578
562
|
actual_worktime = ActualWorktime(df_actual_worktime)
|
|
579
563
|
|
|
580
564
|
if args.annotation_count_csv is not None:
|
|
581
565
|
df_annotation_count = pandas.read_csv(args.annotation_count_csv)
|
|
582
566
|
if not AnnotationCount.required_columns_exist(df_annotation_count):
|
|
583
|
-
logger.error(
|
|
584
|
-
"引数`--annotation_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `annotation_count`"
|
|
585
|
-
)
|
|
567
|
+
logger.error("引数`--annotation_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `annotation_count`")
|
|
586
568
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
587
569
|
annotation_count = AnnotationCount(df_annotation_count)
|
|
588
570
|
else:
|
|
@@ -591,22 +573,16 @@ class VisualizeStatistics(CommandLine):
|
|
|
591
573
|
if args.input_data_count_csv is not None:
|
|
592
574
|
df_input_data_count = pandas.read_csv(args.input_data_count_csv)
|
|
593
575
|
if not InputDataCount.required_columns_exist(df_input_data_count):
|
|
594
|
-
logger.error(
|
|
595
|
-
"引数`--input_data_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `input_data_count`"
|
|
596
|
-
)
|
|
576
|
+
logger.error("引数`--input_data_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `input_data_count`")
|
|
597
577
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
598
578
|
input_data_count = InputDataCount(df_input_data_count)
|
|
599
579
|
else:
|
|
600
580
|
input_data_count = None
|
|
601
581
|
|
|
602
|
-
custom_production_volume = (
|
|
603
|
-
create_custom_production_volume(args.custom_production_volume) if args.custom_production_volume is not None else None
|
|
604
|
-
)
|
|
582
|
+
custom_production_volume = create_custom_production_volume(args.custom_production_volume) if args.custom_production_volume is not None else None
|
|
605
583
|
|
|
606
584
|
ignored_task_id_set = set(get_list_from_args(args.ignored_task_id)) if args.ignored_task_id is not None else None
|
|
607
|
-
filtering_query = FilteringQuery(
|
|
608
|
-
task_query=task_query, start_date=args.start_date, end_date=args.end_date, ignored_task_ids=ignored_task_id_set
|
|
609
|
-
)
|
|
585
|
+
filtering_query = FilteringQuery(task_query=task_query, start_date=args.start_date, end_date=args.end_date, ignored_task_ids=ignored_task_id_set)
|
|
610
586
|
|
|
611
587
|
if args.temp_dir is None:
|
|
612
588
|
with tempfile.TemporaryDirectory() as str_temp_dir:
|
|
@@ -690,11 +666,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
690
666
|
"-u",
|
|
691
667
|
"--user_id",
|
|
692
668
|
nargs="+",
|
|
693
|
-
help=(
|
|
694
|
-
"メンバごとの統計グラフに表示するユーザのuser_idを指定してください。"
|
|
695
|
-
"指定しない場合は、上位20人が表示されます。\n"
|
|
696
|
-
"``file://`` を先頭に付けると、一覧が記載されたファイルを指定できます。"
|
|
697
|
-
),
|
|
669
|
+
help=("メンバごとの統計グラフに表示するユーザのuser_idを指定してください。指定しない場合は、上位20人が表示されます。\n``file://`` を先頭に付けると、一覧が記載されたファイルを指定できます。"),
|
|
698
670
|
)
|
|
699
671
|
|
|
700
672
|
parser.add_argument(
|
|
@@ -714,7 +686,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
714
686
|
"--latest",
|
|
715
687
|
action="store_true",
|
|
716
688
|
help="統計情報の元になるファイル(アノテーションzipなど)の最新版を参照します。このオプションを指定すると、各ファイルを更新するのに5分以上待ちます。\n"
|
|
717
|
-
"ただしWebAPIの都合上、'タスク履歴全件ファイル'は最新版を参照できません。タスク履歴の最新版を参照する場合は ``--get_task_histories_one_of_each`` を指定してください。",
|
|
689
|
+
"ただしWebAPIの都合上、'タスク履歴全件ファイル'は最新版を参照できません。タスク履歴の最新版を参照する場合は ``--get_task_histories_one_of_each`` を指定してください。",
|
|
718
690
|
)
|
|
719
691
|
|
|
720
692
|
parser.add_argument(
|
|
@@ -727,12 +699,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
727
699
|
"--labor_csv",
|
|
728
700
|
type=Path,
|
|
729
701
|
help=(
|
|
730
|
-
"実績作業時間情報が格納されたCSVを指定してください。指定しない場合は、実績作業時間は0とみなします。列名は以下の通りです。\n"
|
|
731
|
-
"\n"
|
|
732
|
-
"* date\n"
|
|
733
|
-
"* account_id\n"
|
|
734
|
-
"* actual_worktime_hour\n"
|
|
735
|
-
"* project_id \n"
|
|
702
|
+
"実績作業時間情報が格納されたCSVを指定してください。指定しない場合は、実績作業時間は0とみなします。列名は以下の通りです。\n\n* date\n* account_id\n* actual_worktime_hour\n* project_id \n"
|
|
736
703
|
),
|
|
737
704
|
)
|
|
738
705
|
|
|
@@ -773,7 +740,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
773
740
|
help=(
|
|
774
741
|
"プロジェクト独自の生産量をJSON形式で指定します。"
|
|
775
742
|
f"(例) ``{json.dumps(custom_production_volume_sample, ensure_ascii=False)}`` \n"
|
|
776
|
-
"詳細は https://annofab-cli.readthedocs.io/ja/latest/command_reference/statistics/visualize.html#custom-project-volume を参照してください。"
|
|
743
|
+
"詳細は https://annofab-cli.readthedocs.io/ja/latest/command_reference/statistics/visualize.html#custom-project-volume を参照してください。"
|
|
777
744
|
),
|
|
778
745
|
)
|
|
779
746
|
|
|
@@ -798,9 +765,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
798
765
|
parser.add_argument(
|
|
799
766
|
"--not_download",
|
|
800
767
|
action="store_true",
|
|
801
|
-
help=(
|
|
802
|
-
"指定した場合、アノテーションZIPなどのファイルをダウンロードせずに、`--temp_dir`で指定したディレクトリ内のファイルを読み込みます。`--temp_dir`は必須です。"
|
|
803
|
-
),
|
|
768
|
+
help=("指定した場合、アノテーションZIPなどのファイルをダウンロードせずに、`--temp_dir`で指定したディレクトリ内のファイルを読み込みます。`--temp_dir`は必須です。"),
|
|
804
769
|
)
|
|
805
770
|
|
|
806
771
|
parser.add_argument(
|
|
@@ -164,19 +164,15 @@ def get_video_duration_list(
|
|
|
164
164
|
if input_data_ids is not None:
|
|
165
165
|
input_data_list = [input_data for input_data in input_data_list if input_data["input_data_id"] in input_data_ids]
|
|
166
166
|
logger.debug(
|
|
167
|
-
f"「入力データのinput_data_idが引数'input_data_ids'に一致する」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'input_data_ids'は {len(input_data_ids)} 件"
|
|
167
|
+
f"「入力データのinput_data_idが引数'input_data_ids'に一致する」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'input_data_ids'は {len(input_data_ids)} 件"
|
|
168
168
|
)
|
|
169
169
|
|
|
170
170
|
if from_datetime is not None:
|
|
171
|
-
input_data_list = [
|
|
172
|
-
input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) >= from_datetime
|
|
173
|
-
]
|
|
171
|
+
input_data_list = [input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) >= from_datetime]
|
|
174
172
|
logger.debug(f"「入力データの更新日時が'{from_datetime}'以降」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。")
|
|
175
173
|
|
|
176
174
|
if to_datetime is not None:
|
|
177
|
-
input_data_list = [
|
|
178
|
-
input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) <= to_datetime
|
|
179
|
-
]
|
|
175
|
+
input_data_list = [input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) <= to_datetime]
|
|
180
176
|
logger.debug(f"「入力データの更新日時が'{to_datetime}'以前」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。")
|
|
181
177
|
|
|
182
178
|
if task_ids is not None:
|
|
@@ -185,9 +181,7 @@ def get_video_duration_list(
|
|
|
185
181
|
input_data_id_list_list = [task["input_data_id_list"] for task in task_list if task["task_id"] in task_ids]
|
|
186
182
|
input_data_ids_included_task = set(itertools.chain.from_iterable(input_data_id_list_list))
|
|
187
183
|
input_data_list = [input_data for input_data in input_data_list if input_data["input_data_id"] in input_data_ids_included_task]
|
|
188
|
-
logger.debug(
|
|
189
|
-
f"「引数'task_ids'に対応するタスクに含まれている入力データ」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'task_ids'は {len(task_ids)} 件" # noqa: E501
|
|
190
|
-
)
|
|
184
|
+
logger.debug(f"「引数'task_ids'に対応するタスクに含まれている入力データ」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'task_ids'は {len(task_ids)} 件")
|
|
191
185
|
|
|
192
186
|
video_duration_list = []
|
|
193
187
|
for input_data in input_data_list:
|
|
@@ -206,7 +200,7 @@ class VisualizeVideoDuration(CommandLine):
|
|
|
206
200
|
def validate(self, args: argparse.Namespace) -> bool:
|
|
207
201
|
if args.project_id is None and (args.input_data_json is None or args.task_json is None):
|
|
208
202
|
print( # noqa: T201
|
|
209
|
-
f"{self.COMMON_MESSAGE} argument --project_id: '--input_data_json'または'--task_json'が未指定のときは、'--project_id' を指定してください。",
|
|
203
|
+
f"{self.COMMON_MESSAGE} argument --project_id: '--input_data_json'または'--task_json'が未指定のときは、'--project_id' を指定してください。",
|
|
210
204
|
file=sys.stderr,
|
|
211
205
|
)
|
|
212
206
|
return False
|
|
@@ -326,8 +320,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
326
320
|
"--input_data_json",
|
|
327
321
|
type=Path,
|
|
328
322
|
required=False,
|
|
329
|
-
help="入力データ情報が記載されたJSONファイルのパスを指定します。\
|
|
330
|
-
"JSONファイルは ``$ annofabcli input_data download`` コマンドで取得できます。",
|
|
323
|
+
help="入力データ情報が記載されたJSONファイルのパスを指定します。\nJSONファイルは ``$ annofabcli input_data download`` コマンドで取得できます。",
|
|
331
324
|
)
|
|
332
325
|
|
|
333
326
|
parser.add_argument(
|
|
@@ -365,18 +358,14 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
365
358
|
"-t",
|
|
366
359
|
"--task_id",
|
|
367
360
|
nargs="+",
|
|
368
|
-
help=(
|
|
369
|
-
"指定したtask_idのタスクに含まれている入力データを可視化対象にします。 ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。" # noqa: E501
|
|
370
|
-
),
|
|
361
|
+
help=("指定したtask_idのタスクに含まれている入力データを可視化対象にします。 ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"),
|
|
371
362
|
)
|
|
372
363
|
|
|
373
364
|
parser.add_argument(
|
|
374
365
|
"-i",
|
|
375
366
|
"--input_data_id",
|
|
376
367
|
nargs="+",
|
|
377
|
-
help=(
|
|
378
|
-
"指定したinput_data_idである入力データを可視化対象にします。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。" # noqa: E501
|
|
379
|
-
),
|
|
368
|
+
help=("指定したinput_data_idである入力データを可視化対象にします。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"),
|
|
380
369
|
)
|
|
381
370
|
|
|
382
371
|
parser.add_argument("--from_date", type=str, help="指定した日付( ``YYYY-MM-DD`` )以降に更新された入力データを可視化対象にします。")
|
|
@@ -84,16 +84,10 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
|
|
|
84
84
|
for supplementary_data_id in supplementary_data_id_list:
|
|
85
85
|
supplementary_data = _get_supplementary_data_list(supplementary_data_id)
|
|
86
86
|
if supplementary_data is None:
|
|
87
|
-
logger.warning(
|
|
88
|
-
f"input_data_id='{input_data_id}' の入力データに、"
|
|
89
|
-
f"supplementary_data_id='{supplementary_data_id}' の補助情報は存在しないのでスキップします。"
|
|
90
|
-
)
|
|
87
|
+
logger.warning(f"input_data_id='{input_data_id}' の入力データに、supplementary_data_id='{supplementary_data_id}' の補助情報は存在しないのでスキップします。")
|
|
91
88
|
continue
|
|
92
89
|
|
|
93
|
-
message_for_confirm =
|
|
94
|
-
f"補助情報 supplementary_data_id='{supplementary_data_id}', "
|
|
95
|
-
f"supplementary_data_name='{supplementary_data['supplementary_data_name']}' を削除しますか?"
|
|
96
|
-
)
|
|
90
|
+
message_for_confirm = f"補助情報 supplementary_data_id='{supplementary_data_id}', supplementary_data_name='{supplementary_data['supplementary_data_name']}' を削除しますか?"
|
|
97
91
|
if not self.confirm_processing(message_for_confirm):
|
|
98
92
|
continue
|
|
99
93
|
|
|
@@ -108,8 +102,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
|
|
|
108
102
|
deleted_count += 1
|
|
109
103
|
except requests.HTTPError:
|
|
110
104
|
logger.warning(
|
|
111
|
-
f"補助情報 supplementary_data_id='{supplementary_data_id}', "
|
|
112
|
-
f"supplementary_data_name='{supplementary_data['supplementary_data_name']}' の削除に失敗しました。",
|
|
105
|
+
f"補助情報 supplementary_data_id='{supplementary_data_id}', supplementary_data_name='{supplementary_data['supplementary_data_name']}' の削除に失敗しました。",
|
|
113
106
|
exc_info=True,
|
|
114
107
|
)
|
|
115
108
|
continue
|
|
@@ -126,9 +119,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
|
|
|
126
119
|
|
|
127
120
|
logger.info(f"{deleted_count} / {total_count} 件の補助情報を削除しました。")
|
|
128
121
|
|
|
129
|
-
def delete_supplementary_data_list_for_input_data2(
|
|
130
|
-
self, project_id: str, input_data_id: str, supplementary_data_list: list[dict[str, Any]]
|
|
131
|
-
) -> int:
|
|
122
|
+
def delete_supplementary_data_list_for_input_data2(self, project_id: str, input_data_id: str, supplementary_data_list: list[dict[str, Any]]) -> int:
|
|
132
123
|
"""
|
|
133
124
|
入力データ配下の補助情報を削除する。
|
|
134
125
|
|
|
@@ -147,8 +138,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
|
|
|
147
138
|
try:
|
|
148
139
|
self.service.api.delete_supplementary_data(project_id, input_data_id=input_data_id, supplementary_data_id=supplementary_data_id)
|
|
149
140
|
logger.debug(
|
|
150
|
-
f"補助情報を削除しました。input_data_id='{input_data_id}', supplementary_data_id='{supplementary_data_id}', "
|
|
151
|
-
f"supplementary_data_name={supplementary_data['supplementary_data_name']}"
|
|
141
|
+
f"補助情報を削除しました。input_data_id='{input_data_id}', supplementary_data_id='{supplementary_data_id}', supplementary_data_name={supplementary_data['supplementary_data_name']}"
|
|
152
142
|
)
|
|
153
143
|
deleted_count += 1
|
|
154
144
|
except requests.HTTPError:
|
|
@@ -175,18 +165,12 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
|
|
|
175
165
|
logger.debug("入力データに紐づく補助情報は存在しないので、削除をスキップします。")
|
|
176
166
|
continue
|
|
177
167
|
|
|
178
|
-
message_for_confirm = (
|
|
179
|
-
f"入力データに紐づく補助情報 {len(supplementary_data_list)} 件を削除しますか? "
|
|
180
|
-
f"(input_data_id='{input_data_id}', "
|
|
181
|
-
f"input_data_name='{input_data_name}') "
|
|
182
|
-
)
|
|
168
|
+
message_for_confirm = f"入力データに紐づく補助情報 {len(supplementary_data_list)} 件を削除しますか? (input_data_id='{input_data_id}', input_data_name='{input_data_name}') "
|
|
183
169
|
if not self.confirm_processing(message_for_confirm):
|
|
184
170
|
continue
|
|
185
171
|
|
|
186
172
|
try:
|
|
187
|
-
deleted_supplementary_data_count = self.delete_supplementary_data_list_for_input_data2(
|
|
188
|
-
project_id, input_data_id, supplementary_data_list
|
|
189
|
-
)
|
|
173
|
+
deleted_supplementary_data_count = self.delete_supplementary_data_list_for_input_data2(project_id, input_data_id, supplementary_data_list)
|
|
190
174
|
dict_deleted_count[input_data_id] = deleted_supplementary_data_count
|
|
191
175
|
logger.debug(
|
|
192
176
|
f"入力データに紐づく補助情報を {deleted_supplementary_data_count} / {len(supplementary_data_list)} 件削除しました。"
|
|
@@ -150,7 +150,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
150
150
|
nargs="+",
|
|
151
151
|
help=(
|
|
152
152
|
"指定したinput_data_idの入力データに紐づく補助情報を出力します。\n"
|
|
153
|
-
"未指定の場合は、入力データ全件ファイルをダウンロードして、すべての入力データに紐づく補助情報を出力します。ただし入力データの数だけAPIを実行するため、出力に時間がかかります。 \n"
|
|
153
|
+
"未指定の場合は、入力データ全件ファイルをダウンロードして、すべての入力データに紐づく補助情報を出力します。ただし入力データの数だけAPIを実行するため、出力に時間がかかります。 \n"
|
|
154
154
|
"``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"
|
|
155
155
|
),
|
|
156
156
|
)
|
|
@@ -152,19 +152,11 @@ class SubPutSupplementaryData:
|
|
|
152
152
|
|
|
153
153
|
return yes
|
|
154
154
|
|
|
155
|
-
def confirm_put_supplementary_data(
|
|
156
|
-
self, csv_supplementary_data: CliSupplementaryData, supplementary_data_id: str, *, already_exists: bool = False
|
|
157
|
-
) -> bool:
|
|
155
|
+
def confirm_put_supplementary_data(self, csv_supplementary_data: CliSupplementaryData, supplementary_data_id: str, *, already_exists: bool = False) -> bool:
|
|
158
156
|
if already_exists:
|
|
159
|
-
message_for_confirm =
|
|
160
|
-
f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', "
|
|
161
|
-
f"supplementary_data_id='{supplementary_data_id}'の補助情報を更新しますか?"
|
|
162
|
-
)
|
|
157
|
+
message_for_confirm = f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', supplementary_data_id='{supplementary_data_id}'の補助情報を更新しますか?"
|
|
163
158
|
else:
|
|
164
|
-
message_for_confirm =
|
|
165
|
-
f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', "
|
|
166
|
-
f"supplementary_data_id='{supplementary_data_id}'の補助情報を登録しますか?"
|
|
167
|
-
)
|
|
159
|
+
message_for_confirm = f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', supplementary_data_id='{supplementary_data_id}'の補助情報を登録しますか?"
|
|
168
160
|
|
|
169
161
|
return self.confirm_processing(message_for_confirm)
|
|
170
162
|
|
|
@@ -172,9 +164,7 @@ class SubPutSupplementaryData:
|
|
|
172
164
|
last_updated_datetime = None
|
|
173
165
|
input_data_id = csv_data.input_data_id
|
|
174
166
|
supplementary_data_id = (
|
|
175
|
-
csv_data.supplementary_data_id
|
|
176
|
-
if csv_data.supplementary_data_id is not None
|
|
177
|
-
else convert_supplementary_data_name_to_supplementary_data_id(csv_data.supplementary_data_name)
|
|
167
|
+
csv_data.supplementary_data_id if csv_data.supplementary_data_id is not None else convert_supplementary_data_name_to_supplementary_data_id(csv_data.supplementary_data_name)
|
|
178
168
|
)
|
|
179
169
|
|
|
180
170
|
supplementary_data_list = self.service.wrapper.get_supplementary_data_list_or_none(project_id, input_data_id)
|
|
@@ -270,7 +260,7 @@ class PutSupplementaryData(CommandLine):
|
|
|
270
260
|
overwrite: Trueならば、supplementary_data_id(省略時はsupplementary_data_number)がすでに存在していたら上書きします。Falseならばスキップします。
|
|
271
261
|
parallelism: 並列度
|
|
272
262
|
|
|
273
|
-
"""
|
|
263
|
+
"""
|
|
274
264
|
|
|
275
265
|
project_title = self.facade.get_project_title(project_id)
|
|
276
266
|
logger.info(f"{project_title} に、{len(supplementary_data_list)} 件の補助情報を登録します。")
|
|
@@ -101,8 +101,7 @@ class CancelAcceptanceMain(CommandLineWithConfirm):
|
|
|
101
101
|
return False
|
|
102
102
|
|
|
103
103
|
logger.debug(
|
|
104
|
-
f"{logging_prefix}: task_id = {task_id}
|
|
105
|
-
f"タスクの担当者は {actual_acceptor.username}({actual_acceptor.user_id}) です。"
|
|
104
|
+
f"{logging_prefix}: task_id = {task_id} のタスクの受入完了状態を取り消します。タスクの担当者は {actual_acceptor.username}({actual_acceptor.user_id}) です。"
|
|
106
105
|
if actual_acceptor is not None
|
|
107
106
|
else "タスクの担当者は未割り当てです。"
|
|
108
107
|
)
|
|
@@ -234,7 +233,7 @@ class CancelAcceptance(CommandLine):
|
|
|
234
233
|
member = more_itertools.first_true(project_member_list, pred=lambda e: e["user_id"] == assigned_acceptor_user_id)
|
|
235
234
|
if member is None:
|
|
236
235
|
print( # noqa: T201
|
|
237
|
-
f"{self.COMMON_MESSAGE} argument --assigned_acceptor_user_id: プロジェクトメンバーに user_id='{assigned_acceptor_user_id}'メンバーは存在しません",
|
|
236
|
+
f"{self.COMMON_MESSAGE} argument --assigned_acceptor_user_id: プロジェクトメンバーに user_id='{assigned_acceptor_user_id}'メンバーは存在しません",
|
|
238
237
|
file=sys.stderr,
|
|
239
238
|
)
|
|
240
239
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
@@ -297,7 +296,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
297
296
|
"--parallelism",
|
|
298
297
|
type=int,
|
|
299
298
|
choices=PARALLELISM_CHOICES,
|
|
300
|
-
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
299
|
+
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
301
300
|
)
|
|
302
301
|
|
|
303
302
|
parser.add_argument("--dryrun", action="store_true", help="取り消しが行われた時の結果を表示しますが、実際は受け入れを取り消しません。")
|
|
@@ -78,13 +78,7 @@ class ChangeOperatorMain:
|
|
|
78
78
|
if task.account_id is not None:
|
|
79
79
|
now_user_id = self.facade.get_user_id_from_account_id(project_id, task.account_id)
|
|
80
80
|
|
|
81
|
-
logger.debug(
|
|
82
|
-
f"{logging_prefix} : task_id = {task.task_id}, "
|
|
83
|
-
f"status = {task.status.value}, "
|
|
84
|
-
f"phase = {task.phase.value}, "
|
|
85
|
-
f"phase_stage = {task.phase_stage}, "
|
|
86
|
-
f"user_id = {now_user_id}"
|
|
87
|
-
)
|
|
81
|
+
logger.debug(f"{logging_prefix} : task_id = {task.task_id}, status = {task.status.value}, phase = {task.phase.value}, phase_stage = {task.phase_stage}, user_id = {now_user_id}")
|
|
88
82
|
|
|
89
83
|
if task.status in [TaskStatus.COMPLETE, TaskStatus.WORKING]:
|
|
90
84
|
logger.warning(f"{logging_prefix} : task_id = {task_id} : タスクのstatusがworking or complete なので、担当者を変更できません。")
|
|
@@ -174,9 +168,7 @@ class ChangeOperatorMain:
|
|
|
174
168
|
# 逐次処理
|
|
175
169
|
for task_index, task_id in enumerate(task_id_list):
|
|
176
170
|
try:
|
|
177
|
-
result = self.change_operator_for_task(
|
|
178
|
-
project_id, task_id, task_index=task_index, task_query=task_query, new_account_id=new_account_id
|
|
179
|
-
)
|
|
171
|
+
result = self.change_operator_for_task(project_id, task_id, task_index=task_index, task_query=task_query, new_account_id=new_account_id)
|
|
180
172
|
if result:
|
|
181
173
|
success_count += 1
|
|
182
174
|
except Exception: # pylint: disable=broad-except
|
|
@@ -254,7 +246,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
254
246
|
"--parallelism",
|
|
255
247
|
type=int,
|
|
256
248
|
choices=PARALLELISM_CHOICES,
|
|
257
|
-
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
249
|
+
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
258
250
|
)
|
|
259
251
|
|
|
260
252
|
parser.set_defaults(subcommand_func=main)
|
|
@@ -204,7 +204,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
204
204
|
"--parallelism",
|
|
205
205
|
type=int,
|
|
206
206
|
choices=PARALLELISM_CHOICES,
|
|
207
|
-
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
207
|
+
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
208
208
|
)
|
|
209
209
|
|
|
210
210
|
parser.set_defaults(subcommand_func=main)
|
|
@@ -40,10 +40,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
|
|
|
40
40
|
if task.account_id is not None:
|
|
41
41
|
user_id = self.facade.get_user_id_from_account_id(self.project_id, task.account_id)
|
|
42
42
|
|
|
43
|
-
confirm_message = (
|
|
44
|
-
f"task_id='{task.task_id}' のタスクのステータスを保留中に変更しますか?"
|
|
45
|
-
f"(status='{task.status.value}, phase='{task.phase.value}', user_id='{user_id}')"
|
|
46
|
-
)
|
|
43
|
+
confirm_message = f"task_id='{task.task_id}' のタスクのステータスを保留中に変更しますか?(status='{task.status.value}, phase='{task.phase.value}', user_id='{user_id}')"
|
|
47
44
|
return self.confirm_processing(confirm_message)
|
|
48
45
|
|
|
49
46
|
def add_comment(self, task: Task, comment: str) -> None:
|
|
@@ -83,16 +80,11 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
|
|
|
83
80
|
|
|
84
81
|
def preprocess() -> bool:
|
|
85
82
|
if not match_task_with_query(task, task_query):
|
|
86
|
-
logger.debug(
|
|
87
|
-
f"{logging_prefix} : task_id = {task_id} : `--task_query` の条件にマッチしないため、スキップします。 :: task_query={task_query}"
|
|
88
|
-
)
|
|
83
|
+
logger.debug(f"{logging_prefix} : task_id = {task_id} : `--task_query` の条件にマッチしないため、スキップします。 :: task_query={task_query}")
|
|
89
84
|
return False
|
|
90
85
|
|
|
91
86
|
if task.status not in [TaskStatus.NOT_STARTED, TaskStatus.BREAK]:
|
|
92
|
-
logger.warning(
|
|
93
|
-
f"{logging_prefix}: task_id = '{task_id}' のタスクのステータスが未着手または休憩中でないので、スキップします。 :: "
|
|
94
|
-
f"status='{task.status.value}'"
|
|
95
|
-
)
|
|
87
|
+
logger.warning(f"{logging_prefix}: task_id = '{task_id}' のタスクのステータスが未着手または休憩中でないので、スキップします。 :: status='{task.status.value}'")
|
|
96
88
|
return False
|
|
97
89
|
|
|
98
90
|
if not self.confirm_change_status_to_on_hold(task): # noqa: SIM103
|
|
@@ -115,10 +107,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
|
|
|
115
107
|
if task.account_id is not None:
|
|
116
108
|
task_user_id = self.facade.get_user_id_from_account_id(self.project_id, task.account_id)
|
|
117
109
|
|
|
118
|
-
logger.debug(
|
|
119
|
-
f"{logging_prefix}: task_id='{task_id}'のステータスを保留中に変更します。 :: "
|
|
120
|
-
f"status='{task.status.value}, phase='{task.phase.value}', user_id='{task_user_id}'"
|
|
121
|
-
)
|
|
110
|
+
logger.debug(f"{logging_prefix}: task_id='{task_id}'のステータスを保留中に変更します。 :: status='{task.status.value}, phase='{task.phase.value}', user_id='{task_user_id}'")
|
|
122
111
|
|
|
123
112
|
task_last_updated_datetime = None
|
|
124
113
|
|
|
@@ -130,9 +119,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
|
|
|
130
119
|
task_last_updated_datetime = updated_task["updated_datetime"]
|
|
131
120
|
logger.debug(f"{logging_prefix}: task_id='{task_id}' のタスクの担当者を'{task_user_id}'から自分自身に変更しました。")
|
|
132
121
|
|
|
133
|
-
updated_task = self.service.wrapper.change_task_status_to_working(
|
|
134
|
-
self.project_id, task_id, last_updated_datetime=task_last_updated_datetime
|
|
135
|
-
)
|
|
122
|
+
updated_task = self.service.wrapper.change_task_status_to_working(self.project_id, task_id, last_updated_datetime=task_last_updated_datetime)
|
|
136
123
|
task_last_updated_datetime = updated_task["updated_datetime"]
|
|
137
124
|
logger.debug(f"{logging_prefix}: task_id='{task_id}'のタスクのステータスを作業中に変更しました。")
|
|
138
125
|
|
|
@@ -144,15 +144,11 @@ class CompleteTasksMain(CommandLineWithConfirm):
|
|
|
144
144
|
try:
|
|
145
145
|
last_updated_datetime = None
|
|
146
146
|
if task.account_id != my_account_id:
|
|
147
|
-
_task = self.service.wrapper.change_task_operator(
|
|
148
|
-
task.project_id, task.task_id, my_account_id, last_updated_datetime=task.updated_datetime
|
|
149
|
-
)
|
|
147
|
+
_task = self.service.wrapper.change_task_operator(task.project_id, task.task_id, my_account_id, last_updated_datetime=task.updated_datetime)
|
|
150
148
|
last_updated_datetime = _task["updated_datetime"]
|
|
151
149
|
logger.debug(f"{task.task_id}: 担当者を自分自身に変更しました。")
|
|
152
150
|
|
|
153
|
-
dict_task = self.service.wrapper.change_task_status_to_working(
|
|
154
|
-
project_id=task.project_id, task_id=task.task_id, last_updated_datetime=last_updated_datetime
|
|
155
|
-
)
|
|
151
|
+
dict_task = self.service.wrapper.change_task_status_to_working(project_id=task.project_id, task_id=task.task_id, last_updated_datetime=last_updated_datetime)
|
|
156
152
|
return Task.from_dict(dict_task)
|
|
157
153
|
|
|
158
154
|
except requests.HTTPError:
|
|
@@ -192,11 +188,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
|
|
|
192
188
|
|
|
193
189
|
comment_list, _ = self.service.api.get_comments(task.project_id, task.task_id, input_data_id, query_params={"v": "2"})
|
|
194
190
|
# 未処置の検査コメント
|
|
195
|
-
unprocessed_inspection_list = [
|
|
196
|
-
e
|
|
197
|
-
for e in comment_list
|
|
198
|
-
if e["comment_type"] == "inspection" and e["comment_node"]["_type"] == "Root" and e["comment_node"]["status"] == "open"
|
|
199
|
-
]
|
|
191
|
+
unprocessed_inspection_list = [e for e in comment_list if e["comment_type"] == "inspection" and e["comment_node"]["_type"] == "Root" and e["comment_node"]["status"] == "open"]
|
|
200
192
|
|
|
201
193
|
unanswered_comment_list = [e for e in unprocessed_inspection_list if not exists_answered_comment(e["comment_id"])]
|
|
202
194
|
return unanswered_comment_list
|
|
@@ -228,9 +220,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
|
|
|
228
220
|
logger.debug(f"{task.task_id}: 未回答の検査コメントが {unanswered_comment_count_for_task} 件あります。")
|
|
229
221
|
if unanswered_comment_count_for_task > 0: # noqa: SIM102
|
|
230
222
|
if reply_comment is None:
|
|
231
|
-
logger.warning(
|
|
232
|
-
f"{task.task_id}: 未回答の検査コメントに対する返信コメント('--reply_comment')が指定されていないので、スキップします。"
|
|
233
|
-
)
|
|
223
|
+
logger.warning(f"{task.task_id}: 未回答の検査コメントに対する返信コメント('--reply_comment')が指定されていないので、スキップします。")
|
|
234
224
|
return False
|
|
235
225
|
|
|
236
226
|
if not self.confirm_processing(f"タスク'{task.task_id}'の教師付フェーズを次のフェーズに進めますか?"):
|
|
@@ -269,9 +259,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
|
|
|
269
259
|
logger.debug(f"{task.task_id}: 未処置の検査コメントが {unprocessed_inspection_count} 件あります。")
|
|
270
260
|
if unprocessed_inspection_count > 0: # noqa: SIM102
|
|
271
261
|
if inspection_status is None:
|
|
272
|
-
logger.warning(
|
|
273
|
-
f"{task.task_id}: 未処置の検査コメントに対する対応方法('--inspection_status')が指定されていないので、スキップします。"
|
|
274
|
-
)
|
|
262
|
+
logger.warning(f"{task.task_id}: 未処置の検査コメントに対する対応方法('--inspection_status')が指定されていないので、スキップします。")
|
|
275
263
|
return False
|
|
276
264
|
|
|
277
265
|
if not self.confirm_processing(f"タスク'{task.task_id}'の検査/受入フェーズを次のフェーズに進めますか?"):
|
|
@@ -331,9 +319,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
|
|
|
331
319
|
return False
|
|
332
320
|
|
|
333
321
|
task: Task = Task.from_dict(dict_task)
|
|
334
|
-
logger.info(
|
|
335
|
-
f"{logging_prefix} : タスク情報 task_id='{task_id}', phase={task.phase.value}, phase_stage={task.phase_stage}, status={task.status.value}"
|
|
336
|
-
)
|
|
322
|
+
logger.info(f"{logging_prefix} : タスク情報 task_id='{task_id}', phase={task.phase.value}, phase_stage={task.phase_stage}, status={task.status.value}")
|
|
337
323
|
if not self._validate_task(task, target_phase=target_phase, target_phase_stage=target_phase_stage, task_query=task_query):
|
|
338
324
|
return False
|
|
339
325
|
|
|
@@ -456,10 +442,7 @@ class CompleteTasks(CommandLine):
|
|
|
456
442
|
logger.warning(f"'--phase'に'{TaskPhase.ANNOTATION.value}'を指定しているとき、'--inspection_status'の値は無視されます。")
|
|
457
443
|
elif args.phase in [TaskPhase.INSPECTION.value, TaskPhase.ACCEPTANCE.value]: # noqa: SIM102
|
|
458
444
|
if args.reply_comment is not None:
|
|
459
|
-
logger.warning(
|
|
460
|
-
f"'--phase'に'{TaskPhase.INSPECTION.value}'または'{TaskPhase.ACCEPTANCE.value}'を指定しているとき、"
|
|
461
|
-
f"'--reply_comment'の値は無視されます。"
|
|
462
|
-
)
|
|
445
|
+
logger.warning(f"'--phase'に'{TaskPhase.INSPECTION.value}'または'{TaskPhase.ACCEPTANCE.value}'を指定しているとき、'--reply_comment'の値は無視されます。")
|
|
463
446
|
|
|
464
447
|
if args.parallelism is not None and not args.yes:
|
|
465
448
|
print( # noqa: T201
|
|
@@ -547,7 +530,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
547
530
|
"--parallelism",
|
|
548
531
|
type=int,
|
|
549
532
|
choices=PARALLELISM_CHOICES,
|
|
550
|
-
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
533
|
+
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
551
534
|
)
|
|
552
535
|
|
|
553
536
|
parser.set_defaults(subcommand_func=main)
|
annofabcli/task/copy_tasks.py
CHANGED
|
@@ -203,8 +203,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
203
203
|
type=str,
|
|
204
204
|
nargs="+",
|
|
205
205
|
required=True,
|
|
206
|
-
help="コピー元のtask_idとコピー先のtask_idを ``:`` で区切って指定してください。\n"
|
|
207
|
-
"``file://`` を先頭に付けると、コピー元とコピー先が記載されているファイルを指定できます。",
|
|
206
|
+
help="コピー元のtask_idとコピー先のtask_idを ``:`` で区切って指定してください。\n``file://`` を先頭に付けると、コピー元とコピー先が記載されているファイルを指定できます。",
|
|
208
207
|
)
|
|
209
208
|
|
|
210
209
|
parser.add_argument("--copy_metadata", action="store_true", help="指定した場合、タスクのメタデータもコピーします。")
|
|
@@ -213,7 +212,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
213
212
|
"--parallelism",
|
|
214
213
|
type=int,
|
|
215
214
|
choices=PARALLELISM_CHOICES,
|
|
216
|
-
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
215
|
+
help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
|
|
217
216
|
)
|
|
218
217
|
|
|
219
218
|
parser.set_defaults(subcommand_func=main)
|
|
@@ -82,17 +82,13 @@ class DeleteMetadataKeysOfTaskMain(CommandLineWithConfirm):
|
|
|
82
82
|
# メタデータを更新する必要がないのでreturnします。
|
|
83
83
|
return False
|
|
84
84
|
|
|
85
|
-
if not self.all_yes and not self.confirm_processing(
|
|
86
|
-
f"task_id='{task_id}' :: metadata='{str_old_metadata}' からキー'{deleted_keys}'を削除しますか?"
|
|
87
|
-
):
|
|
85
|
+
if not self.all_yes and not self.confirm_processing(f"task_id='{task_id}' :: metadata='{str_old_metadata}' からキー'{deleted_keys}'を削除しますか?"):
|
|
88
86
|
return False
|
|
89
87
|
|
|
90
88
|
request_body = {task_id: new_metadata}
|
|
91
89
|
self.service.api.patch_tasks_metadata(self.project_id, request_body=request_body)
|
|
92
90
|
str_new_metadata = json.dumps(new_metadata)
|
|
93
|
-
logger.debug(
|
|
94
|
-
f"{logging_prefix} task_id='{task_id}' :: タスクのメタデータからキー'{deleted_keys}'を削除しました。 :: metadata='{str_new_metadata}'"
|
|
95
|
-
)
|
|
91
|
+
logger.debug(f"{logging_prefix} task_id='{task_id}' :: タスクのメタデータからキー'{deleted_keys}'を削除しました。 :: metadata='{str_new_metadata}'")
|
|
96
92
|
return True
|
|
97
93
|
|
|
98
94
|
def delete_metadata_keys_for_one_task_wrapper(self, tpl: tuple[int, str], metadata_keys: Collection[str]) -> bool:
|