A User-Focused Photo & File Management System
This report summarizes scanner evidence for TagStudioDev/TagStudio, a Python project with 7,238 GitHub stars. SynthScan examined 55,794 lines of code across 283 source files, recording 399 pattern matches distributed across 16 syntactic categories. The legacy adjusted pattern signal is 15.1 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 254 finding(s).
Are imports declared and package/API names verified? 39 finding(s).
Are wrappers, guards, and repeated structures necessary? 263 finding(s).
Which changes need focused human review? 399 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 399 distinct pattern matches across 16 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 431 | self.main_window.menu_bar.open_library_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 439 | self.main_window.menu_bar.save_library_backup_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 444 | self.main_window.menu_bar.settings_action.triggered.connect(self.open_settings_modal) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 455 | self.main_window.menu_bar.open_on_start_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 460 | self.main_window.menu_bar.refresh_dir_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 465 | self.main_window.menu_bar.close_library_action.triggered.connect(self.close_library) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 470 | self.main_window.menu_bar.new_tag_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 474 | self.main_window.menu_bar.select_all_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 478 | self.main_window.menu_bar.select_inverse_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 482 | self.main_window.menu_bar.clear_select_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 488 | self.main_window.menu_bar.copy_fields_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 492 | self.main_window.menu_bar.paste_fields_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 496 | self.main_window.menu_bar.add_tag_to_selected_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 500 | self.main_window.menu_bar.delete_file_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 504 | self.main_window.menu_bar.tag_manager_action.triggered.connect(self.tag_manager.show) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 506 | self.main_window.menu_bar.color_manager_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 510 | self.main_window.menu_bar.field_template_manager_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 523 | self.main_window.menu_bar.library_info_action.triggered.connect(create_library_info_window) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 530 | self.main_window.menu_bar.show_filenames_action.triggered.connect(on_show_filenames_action) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 540 | self.main_window.menu_bar.decrease_thumbnail_size_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 549 | self.main_window.menu_bar.increase_thumbnail_size_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 562 | self.main_window.menu_bar.fix_unlinked_entries_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 571 | self.main_window.menu_bar.fix_ignored_entries_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 580 | self.main_window.menu_bar.fix_dupe_files_action.triggered.connect(create_dupe_files_modal) | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 583 | self.main_window.menu_bar.clear_thumb_cache_action.triggered.connect( | CODE |
| CRITICAL⚡ | src/tagstudio/qt/qt_driver.py | 595 | self.main_window.menu_bar.folders_to_tags_action.triggered.connect( | CODE |
| CRITICAL | src/tagstudio/qt/qt_driver.py | 607 | self.main_window.menu_bar.about_action.triggered.connect(create_about_modal) | CODE |
| CRITICAL | src/tagstudio/qt/qt_driver.py | 608 | self.main_window.menu_bar.changelog_action.triggered.connect(self.show_changelog) | CODE |
| CRITICAL | src/tagstudio/qt/qt_driver.py | 759 | self.main_window.menu_bar.ignore_modal_action.triggered.disconnect() | CODE |
| CRITICAL | src/tagstudio/qt/qt_driver.py | 771 | self.main_window.menu_bar.ignore_modal_action.triggered.connect(self.ignore_modal.show) | CODE |
| CRITICAL | src/tagstudio/qt/mixed/tag_color_manager.py | 129 | else self.driver.main_window.preview_panel.containers.update_from_entry( # noqa: E501 | CODE |
| CRITICAL | src/tagstudio/qt/mixed/tag_color_manager.py | 146 | else self.driver.main_window.preview_panel.containers.update_from_entry( # noqa: E501 | CODE |
| CRITICAL | src/tagstudio/qt/mixed/item_thumb.py | 502 | self.driver.main_window.preview_panel.containers.update_toggled_tag( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/core/test_decompression.py | 31 | def test_unsupported_compression_format(tmp_path: Path): | CODE |
| LOW | tests/core/test_decompression.py | 53 | def test_inner_and_display_ext(filename: str, inner_ext: str | None, display_ext: str): | CODE |
| LOW | tests/core/test_decompression.py | 70 | def test_decompressed_uncompressed_file(tmp_path: Path): | CODE |
| LOW | tests/core/test_decompression.py | 78 | def test_decompressed_compressed_file(tmp_path: Path): | CODE |
| LOW | tests/core/test_decompression.py | 90 | def test_decompressed_too_large(tmp_path: Path): | CODE |
| LOW | tests/core/test_decompression.py | 98 | def test_decompressed_corrupt_file(tmp_path: Path): | CODE |
| LOW | tests/core/test_base_driver.py | 23 | def test_verify_library_path_missing(): | CODE |
| LOW | tests/core/test_base_driver.py | 41 | def test_verify_library_path_not_a_library(tmp_path: Path): | CODE |
| LOW | tests/core/test_base_driver.py | 60 | def test_verify_library_path_allow_creation(tmp_path: Path): | CODE |
| LOW | tests/core/test_base_driver.py | 71 | def test_verify_library_path_existing_library(library_dir: Path): | CODE |
| LOW | tests/core/test_media_types.py | 12 | def test_register_and_contains(): | CODE |
| LOW⚡ | tests/core/test_media_types.py | 27 | def test_contains_missing_group_raises_error(): | CODE |
| LOW⚡ | tests/core/test_media_types.py | 32 | def test_dot_notation_chains_to_parents(): | CODE |
| LOW⚡ | tests/core/test_media_types.py | 40 | def test_explicit_chain_group(): | CODE |
| LOW⚡ | tests/core/test_media_types.py | 47 | def test_equivalent_extensions(): | CODE |
| LOW⚡ | tests/core/test_media_types.py | 56 | def test_get_equivalent_exts_defaults_to_itself(): | CODE |
| LOW | tests/core/test_media_types.py | 89 | def test_add_name_aliases_and_lookup(): | CODE |
| LOW | tests/core/library/test_library.py | 51 | def test_library_update_alias(library: Library, generate_tag: Callable[..., Tag]): | CODE |
| LOW | tests/core/library/test_library.py | 175 | def test_search_library_case_insensitive(library: Library): | CODE |
| LOW | tests/core/library/test_library.py | 205 | def test_remove_text_field_entry_with_multiple_fields(library: Library, entry_full: Entry): | CODE |
| LOW | tests/core/library/test_library.py | 232 | def test_update_entry_with_multiple_identical_text_fields(library: Library, entry_full: Entry): | CODE |
| LOW | tests/core/library/test_library.py | 356 | def test_remove_tags_from_entries(library: Library, entry_full: Entry): | CODE |
| LOW⚡ | tests/core/library/test_library.py | 393 | def test_path_search_default_with_sep(library: Library): | CODE |
| LOW⚡ | tests/core/library/test_library.py | 399 | def test_path_search_glob_after(library: Library): | CODE |
| LOW⚡ | tests/core/library/test_library.py | 405 | def test_path_search_glob_in_front(library: Library): | CODE |
| LOW⚡ | tests/core/library/test_library.py | 411 | def test_path_search_glob_both_sides(library: Library): | CODE |
| LOW⚡ | tests/core/library/test_library.py | 418 | def test_path_search_ilike_glob_equality(library: Library): | CODE |
| LOW | tests/core/library/test_library.py | 441 | def test_path_search_like_glob_equality(library: Library): | CODE |
| LOW | tests/core/library/test_library.py | 470 | def test_filetype_return_one_filetype( | CODE |
| LOW | tests/core/library/test_migrations.py | 61 | def test_migration_with_existing_field_template_tables(tmp_path: Path): | CODE |
| LOW | tests/core/library/test_refresh.py | 34 | def test_refresh_multi_byte_filenames(library: Library): | CODE |
| LOW | tests/core/library/test_unlinked_entries.py | 20 | def test_refresh_unlinked_entries(library: Library): | CODE |
| LOW | tests/qt/test_flow_widget.py | 11 | def test_flow_layout_happy_path(): | CODE |
| LOW | tests/qt/test_field_containers.py | 15 | def test_update_selection_empty(qt_driver: QtDriver): | CODE |
| LOW | tests/qt/test_field_containers.py | 28 | def test_update_selection_single(qt_driver: QtDriver, entry_full: Entry): | CODE |
| LOW | tests/qt/test_field_containers.py | 40 | def test_update_selection_multiple(qt_driver: QtDriver): | CODE |
| LOW | tests/qt/test_field_containers.py | 55 | def test_add_tag_to_selection_single(qt_driver: QtDriver, entry_full: Entry): | CODE |
| LOW | tests/qt/test_field_containers.py | 72 | def test_add_same_tag_to_selection_single(qt_driver: QtDriver, entry_full: Entry): | CODE |
| LOW | tests/qt/test_field_containers.py | 89 | def test_add_tag_to_selection_multiple(qt_driver: QtDriver): | CODE |
| LOW⚡ | tests/qt/test_field_containers.py | 190 | def test_exclude_tag_category( | CODE |
| LOW | tests/qt/test_field_containers.py | 213 | def test_exclude_self_from_tag_category( | CODE |
| LOW | tests/qt/test_field_containers.py | 236 | def test_exclude_self_from_tag_category_without_parent( | CODE |
| LOW | tests/qt/test_theme_system.py | 23 | def test_theme_colorscheme_handling(theme: Theme, expected_call): | CODE |
| LOW⚡ | tests/qt/test_edit_tag_panel.py | 186 | def test_edit_tag_panel_set_tag(qtbot: QtBot, library: Library, generate_tag: Callable[..., Tag]): | CODE |
| LOW⚡ | tests/qt/test_edit_tag_panel.py | 195 | def test_edit_tag_panel_build_tag(qtbot: QtBot, library: Library): | CODE |
| LOW⚡ | tests/qt/test_edit_tag_panel.py | 204 | def test_edit_tag_panel_show_category_from_parent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 28 | def test_edit_tag_panel_add_tag_callback(qt_driver: QtDriver): | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 45 | def test_edit_tag_panel_add_sub_tag_callback( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 59 | def test_edit_tag_panel_remove_subtag_callback( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 82 | def test_edit_tag_panel_add_alias_callback( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 95 | def test_edit_tag_panel_remove_alias_callback( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 120 | def test_edit_tag_panel_set_parent_tags( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 137 | def test_edit_tag_panel_add_aliases( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 168 | def test_edit_tag_panel_set_aliases( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 218 | def test_edit_tag_panel_show_category_from_grandparent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 233 | def test_edit_tag_panel_add_category_through_parent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 252 | def test_edit_tag_panel_add_category_through_grandparent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 272 | def test_edit_tag_panel_remove_category_through_parent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 290 | def test_edit_tag_panel_remove_category_through_grandparent( | CODE |
| LOW | tests/qt/test_edit_tag_panel.py | 309 | def test_edit_tag_panel_exclude_from_category( | CODE |
| 93 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/core/library/json/library.py | 1694 | def update_tag(self, tag: Tag) -> None: | CODE |
| LOW | src/tagstudio/core/library/json/library.py | 1833 | def update_entry_path(self, entry_id: int, path: str | Path) -> None: | CODE |
| LOW | src/tagstudio/core/library/json/library.py | 1837 | def update_entry_filename(self, entry_id: int, filename: str | Path) -> None: | CODE |
| LOW | src/tagstudio/core/library/alchemy/library.py | 1629 | def update_color(self, old_color_group: TagColorGroup, new_color_group: TagColorGroup) -> None: | CODE |
| LOW | src/tagstudio/core/library/alchemy/migrations.py | 160 | def _set_version(self, key: str, value: int) -> None: | CODE |
| LOW | src/tagstudio/qt/qt_driver.py | 1355 | def update_completions_list(self, text: str) -> None: | CODE |
| LOW | src/tagstudio/qt/qt_driver.py | 1480 | def update_browsing_state(self, state: BrowsingState | None = None) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/mixed/field_widget.py | 116 | def set_copy_callback(self, callback: Callable[[], None] | None = None) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/mixed/field_widget.py | 124 | def set_edit_callback(self, callback: Callable[[], None] | None = None) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/mixed/field_widget.py | 132 | def set_remove_callback(self, callback: Callable[[], None] | None = None) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/mixed/field_widget.py | 140 | def set_inner_widget(self, widget: FieldWidget) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/field_widget.py | 155 | def set_title(self, title: str) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/file_attributes.py | 96 | def update_date_label(self, filepath: Path | None = None) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/media_player.py | 277 | def set_tint_opacity(self, opacity: int) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/media_player.py | 458 | def _update_controls(self, size: QSize) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 339 | def set_mode(self, mode: ItemType | None) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 365 | def set_extension(self, filename: Path) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 398 | def set_count(self, count: str) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/field_containers.py | 103 | def update_from_entry(self, entry_id: int, update_badges: bool = True) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/field_containers.py | 139 | def update_toggled_tag(self, tag_id: int, toggle_value: bool) -> None: | CODE |
| LOW | src/tagstudio/qt/mixed/field_containers.py | 460 | def update_datetime_field(self, field: DatetimeField, name: str, value: str) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/tag_box.py | 36 | def set_entries(self, entries: list[int]) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/file_opener_label.py | 30 | def set_file_path(self, filepath: Path) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/controllers/capsule.py | 61 | def set_edit_enabled(self, enabled: bool) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/controllers/capsule.py | 65 | def set_text(self, text: str) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/controllers/capsule.py | 68 | def set_color_group(self, color_group: TagColorGroup | None) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/info_button.py | 126 | def _set_opacity(self, opacity: float) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/info_button.py | 136 | def _update_icon(self, hovered: bool) -> None: | CODE |
| LOW | …/tagstudio/qt/controllers/edit_field_template_modal.py | 45 | def set_field_template(self, field_template: BaseFieldTemplate | None = None) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/field_suggest_box.py | 93 | def _update_hint_icon(self) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/field_suggest_box.py | 106 | def _set_item_widget(self, item: BaseFieldTemplate | None, index: int) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/inspector.py | 163 | def _set_selection_callback(self) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/inspector.py | 227 | def set_selection(self, selected: list[int], update_preview: bool = True) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/tag_suggest_box.py | 111 | def _update_hint_icon(self) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/tag_suggest_box.py | 137 | def _set_item_widget(self, item: Tag | None, index: int) -> None: | CODE |
| LOW | …agstudio/qt/controllers/field_template_search_panel.py | 115 | def set_item_widget(self, item: BaseFieldTemplate | None, index: int) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/edit_tag_panel.py | 182 | def _set_color_button(self, color_group: TagColorGroup | None) -> None: | CODE |
| LOW⚡ | src/tagstudio/qt/controllers/edit_tag_panel.py | 268 | def update_category_exclusion(category_tag: Tag, checked: bool) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/search_panel.py | 92 | def set_limit_items(self, limit_items: list[tuple[str, int]]) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/search_panel.py | 103 | def set_limit_index(self, index: int) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/search_panel.py | 191 | def update_items(self, query: str | None = None) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/search_panel.py | 240 | def set_item_widget(self, item: T | None, index: int) -> None: # pyright: ignore[reportUnusedParameter] | CODE |
| LOW | src/tagstudio/qt/controllers/tag_search_panel.py | 114 | def set_item_widget(self, item: Tag | None, index: int) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 111 | def set_placeholder_text(self, text: str) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 134 | def set_hint_icon(self, icon: Image.Image | None) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 256 | def _update_hint_icon(self) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 259 | def _update_items(self, query: str | None = None) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 319 | def _update_search_field_style(self) -> None: | CODE |
| LOW | src/tagstudio/qt/controllers/suggest_box.py | 331 | def _set_item_widget(self, item: T | None, index: int) -> None: # pyright: ignore[reportUnusedParameter] | CODE |
| LOW | src/tagstudio/qt/controllers/horizontal_scroll_area.py | 19 | def set_inverted(self, is_inverted: bool) -> None: | CODE |
| LOW | src/tagstudio/qt/views/thumb_button.py | 93 | def set_selected(self, value: bool) -> None: | CODE |
| LOW | src/tagstudio/qt/views/tag_box_view.py | 36 | def set_tags(self, tags: Iterable[Tag]) -> None: | CODE |
| LOW | src/tagstudio/qt/views/styles/palette.py | 29 | def set_palette(palette: QPalette) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/core/media_types.py | 190 | CODE | |
| LOW | src/tagstudio/core/query_lang/tokenizer.py | 71 | CODE | |
| LOW | src/tagstudio/core/query_lang/tokenizer.py | 99 | CODE | |
| LOW | src/tagstudio/core/query_lang/ast.py | 101 | CODE | |
| LOW | src/tagstudio/core/library/ignore.py | 198 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 231 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 858 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 943 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 1004 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 1222 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/library.py | 1317 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/visitors.py | 58 | CODE | |
| LOW | src/tagstudio/core/library/alchemy/visitors.py | 175 | CODE | |
| LOW | …o/core/library/alchemy/registries/unlinked_registry.py | 70 | CODE | |
| LOW | …core/library/alchemy/registries/dupe_files_registry.py | 29 | CODE | |
| LOW | src/tagstudio/qt/cache_manager.py | 150 | CODE | |
| LOW | src/tagstudio/qt/qt_driver.py | 959 | CODE | |
| LOW | src/tagstudio/qt/qt_driver.py | 1274 | CODE | |
| LOW | src/tagstudio/qt/qt_driver.py | 1355 | CODE | |
| LOW | src/tagstudio/qt/qt_driver.py | 1433 | CODE | |
| LOW | src/tagstudio/qt/mixed/folders_to_tags.py | 104 | CODE | |
| LOW | src/tagstudio/qt/mixed/drop_import_modal.py | 103 | CODE | |
| LOW | src/tagstudio/qt/mixed/drop_import_modal.py | 185 | CODE | |
| LOW | src/tagstudio/qt/mixed/file_attributes.py | 129 | CODE | |
| LOW | src/tagstudio/qt/mixed/media_player.py | 327 | CODE | |
| LOW | src/tagstudio/qt/mixed/pagination.py | 122 | CODE | |
| LOW | src/tagstudio/qt/utils/file_opener.py | 18 | CODE | |
| LOW | src/tagstudio/qt/controllers/autofill_line_edit.py | 41 | CODE | |
| LOW | src/tagstudio/qt/controllers/field_suggest_box.py | 93 | CODE | |
| LOW | src/tagstudio/qt/controllers/inspector.py | 171 | CODE | |
| LOW | src/tagstudio/qt/controllers/inspector.py | 227 | CODE | |
| LOW | src/tagstudio/qt/controllers/tag_suggest_box.py | 111 | CODE | |
| LOW | src/tagstudio/qt/controllers/preview_thumb.py | 40 | CODE | |
| LOW | src/tagstudio/qt/controllers/preview_thumb.py | 119 | CODE | |
| LOW | src/tagstudio/qt/controllers/changelog_modal.py | 153 | CODE | |
| LOW | src/tagstudio/qt/controllers/changelog_modal.py | 173 | CODE | |
| LOW | src/tagstudio/qt/controllers/edit_tag_panel.py | 213 | CODE | |
| LOW | src/tagstudio/qt/helpers/mnemonics.py | 38 | CODE | |
| LOW | src/tagstudio/qt/helpers/mnemonics.py | 126 | CODE | |
| LOW | src/tagstudio/previews/file_renderer.py | 514 | CODE | |
| LOW | src/tagstudio/previews/file_renderer.py | 706 | CODE | |
| LOW | src/tagstudio/previews/renderers/ebook.py | 60 | CODE | |
| LOW | src/tagstudio/previews/renderers/paint_dot_net.py | 45 | CODE | |
| LOW | src/tagstudio/previews/renderers/archive.py | 145 | CODE | |
| LOW | src/tagstudio/previews/renderers/medibang_paint.py | 44 | CODE | |
| LOW | src/tagstudio/previews/renderers/audio.py | 69 | CODE | |
| LOW | src/tagstudio/previews/renderers/audio.py | 110 | CODE | |
| LOW | src/tagstudio/previews/renderers/video.py | 56 | CODE | |
| LOW | src/tagstudio/previews/vendored/blender_thumbnailer.py | 16 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 181 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 491 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 647 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 857 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 1082 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/utils.py | 17 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | src/tagstudio/qt/mixed/pagination.py | 36 | # -------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/qt/views/edit_tag_panel_view.py | 127 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/previews/vendored/blender_thumbnailer.py | 48 | # -------------------------------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/previews/vendored/blender_thumbnailer.py | 60 | # -------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 79 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 89 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 96 | # -------------------------------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/previews/vendored/blender_thumbnailer.py | 110 | # -------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 146 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 150 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 154 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | src/tagstudio/previews/vendored/blender_thumbnailer.py | 162 | # ---------------------------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/previews/vendored/blender_thumbnailer.py | 180 | # -------------------------------------------------------------- | COMMENT |
| MEDIUM | src/tagstudio/previews/vendored/blender_thumbnailer.py | 186 | # -------------------------------------------------------------- | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/core/library/test_migrations.py | 54 | except Exception as e: | CODE |
| LOW | src/tagstudio/__main__.py | 65 | except Exception: | CODE |
| LOW | src/tagstudio/core/ts_core.py | 34 | except Exception as e: | CODE |
| LOW | src/tagstudio/core/library/refresh.py | 110 | except Exception as e: | CODE |
| LOW | src/tagstudio/core/library/json/library.py | 397 | except Exception: | CODE |
| LOW | src/tagstudio/core/library/alchemy/library.py | 321 | except Exception as e: | CODE |
| LOW | src/tagstudio/core/library/alchemy/library.py | 479 | except Exception as e: | CODE |
| LOW | src/tagstudio/core/library/alchemy/library.py | 1809 | except Exception as e: | CODE |
| LOW | src/tagstudio/core/library/alchemy/migrations.py | 132 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/qt_driver.py | 1675 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/mixed/migration_modal.py | 379 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/mixed/migration_modal.py | 423 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 57 | except Exception: | CODE |
| LOW | src/tagstudio/qt/utils/file_opener.py | 99 | except Exception: | CODE |
| LOW | src/tagstudio/qt/utils/file_deleter.py | 41 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/utils/file_deleter.py | 55 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/controllers/inspector.py | 275 | except Exception as e: | CODE |
| LOW | src/tagstudio/qt/controllers/edit_tag_panel.py | 432 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/file_renderer.py | 597 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/file_renderer.py | 753 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/clip_studio.py | 65 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/ebook.py | 82 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/raster_image.py | 121 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/blender.py | 63 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/paint_dot_net.py | 75 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/archive.py | 174 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/medibang_paint.py | 80 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/renderers/audio.py | 193 | except Exception as e: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 25 | except Exception: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 191 | except Exception: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 286 | except Exception: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 406 | except Exception: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 531 | except Exception: | CODE |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 690 | except Exception: | CODE |
| MEDIUM | src/tagstudio/previews/vendored/pydub/audio_segment.py | 283 | def __eq__(self, other): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/tagstudio/qt/qt_driver.py | 129 | except RuntimeError: | CODE |
| HIGH | src/tagstudio/qt/controllers/preview_thumb.py | 58 | except ( | CODE |
| HIGH | src/tagstudio/qt/views/layouts/thumb_grid_layout.py | 210 | except ValueError: | CODE |
| HIGH | src/tagstudio/previews/file_renderer.py | 668 | except TypeError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/tagstudio/core/library/json/library.py | 493 | # Step 1: Verify default built-in tags are present. | COMMENT |
| LOW⚡ | src/tagstudio/core/library/json/library.py | 497 | # Step 2: Create a Tag object and append it to the internal Tags list, | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 532 | # Step 3: Map each Tag's subtags together now that all Tag objects in it. | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 633 | # Step 1: Create a Collation object and append it to | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 1934 | # NOTE: The following commented-out code enables the ability | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 132 | # NOTE: This method will be replaced with frontend specific decorations (Qt painting) | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 156 | # NOTE: This method will be replaced with frontend specific decorations (Qt painting) | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 218 | # NOTE: This method will be replaced with frontend specific decorations (Qt painting) | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 249 | # NOTE: This method will be replaced with frontend specific decorations (Qt painting) | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 477 | # NOTE: This method will be replaced with frontend specific decorations (Qt painting) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/core/library/json/library.py | 61 | # self.mask: list[id] = None | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 301 | COMMENT | |
| LOW | src/tagstudio/core/library/json/library.py | 341 | self.ext_list: list[str] = [] | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 681 | self.filename_to_entry_id_map[(entry.path / entry.filename)] = entry.id | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 1161 | COMMENT | |
| LOW | src/tagstudio/core/library/json/library.py | 1421 | # Assume that this ID from the cluster is not in the Entry. | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 1441 | # Since this term could technically map to multiple IDs, iterate over it | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 1501 | context: list[str] = None, | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 1521 | # # print( | COMMENT |
| LOW | …tudio/resources/templates/ts_ignore_template_blank.txt | 1 | # This is a '.ts_ignore' file for TagStudio. | COMMENT |
| LOW | …c/tagstudio/resources/templates/ts_ignore_template.txt | 1 | # This is a '.ts_ignore' file for TagStudio. | COMMENT |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 141 | COMMENT | |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 161 | self.top_layout.setObjectName("topLayout") | COMMENT |
| LOW | src/tagstudio/qt/mixed/item_thumb.py | 221 | # self.item_type_badge.setPixmap( | COMMENT |
| LOW | src/tagstudio/previews/vendored/blender_thumbnailer.py | 41 | COMMENT | |
| LOW | src/tagstudio/previews/vendored/blender_thumbnailer.py | 81 | # | COMMENT |
| LOW | src/tagstudio/previews/vendored/blender_thumbnailer.py | 101 | # 7 pointer size | COMMENT |
| LOW | src/tagstudio/previews/vendored/blender_thumbnailer.py | 141 | if len(bhead) < sizeof_bhead: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/tagstudio/qt/qt_driver.py | 1487 | self.browsing_history.push(state) | CODE |
| HIGH | src/tagstudio/qt/controllers/changelog_modal.py | 206 | span = (fragment.position(), fragment.length()) | CODE |
| HIGH | src/tagstudio/qt/controllers/changelog_modal.py | 291 | self._image_widths[url.toString()] or image.width(), | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/qt/test_field_containers.py | 144 | # Check if the container is the Meta Tags category | COMMENT |
| LOW | tests/qt/test_field_containers.py | 148 | # Check if the container is the Tags category | COMMENT |
| LOW⚡ | tests/qt/test_field_containers.py | 177 | # Check if the container is the Meta Tags category | COMMENT |
| LOW⚡ | tests/qt/test_field_containers.py | 181 | # Check if the container is the custom "foo" category | COMMENT |
| LOW | src/tagstudio/previews/file_renderer.py | 658 | # Check if the file is supposed to be ignored and render an overlay if needed | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | src/tagstudio/core/library/ignore.py | 61 | # Create a version of a prefix-less pattern that starts with "**/" | COMMENT |
| MEDIUM | src/tagstudio/previews/renderers/vector_image.py | 57 | # Create an image to draw the svg to and a painter to do the drawing | COMMENT |
| MEDIUM | src/tagstudio/previews/renderers/vector_image.py | 61 | # Create an svg renderer, then render to the painter | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/tagstudio/core/library/json/library.py | 493 | # Step 1: Verify default built-in tags are present. | COMMENT |
| LOW⚡ | src/tagstudio/core/library/json/library.py | 497 | # Step 2: Create a Tag object and append it to the internal Tags list, | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 532 | # Step 3: Map each Tag's subtags together now that all Tag objects in it. | COMMENT |
| LOW | src/tagstudio/core/library/json/library.py | 633 | # Step 1: Create a Collation object and append it to | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/core/library/alchemy/models.py | 137 | CODE | |
| LOW | src/tagstudio/core/utils/silent_subprocess.py | 15 | CODE | |
| LOW | src/tagstudio/core/utils/silent_subprocess.py | 92 | CODE | |
| LOW | src/tagstudio/previews/vendored/pydub/audio_segment.py | 857 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/qt/views/underlined_widget_view.py | 18 | # HACK: I don't know why I can't just use a QFrame for the outline. | COMMENT |
| LOW | src/tagstudio/previews/vendored/pydub/utils.py | 54 | # If ffprobe didn't give any information, just return it | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tagstudio/core/library/alchemy/fields.py | 5 | CODE | |
| LOW | src/tagstudio/qt/qt_driver.py | 43 | CODE | |
| LOW | src/tagstudio/previews/renderers/raster_image.py | 27 | CODE |