Generate audiobooks from EPUBs, PDFs and text with synchronized captions.
This report presents the forensic synthetic code analysis of denizsafak/abogen, a Python project with 5,478 GitHub stars. SynthScan v2.0 examined 85,158 lines of code across 305 source files, recording 2163 pattern matches distributed across 17 syntactic categories. The overall adjusted score of 33.8 places this repository in the Strong AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 2163 distinct pattern matches across 17 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. 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 diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | plugins/supertonic/__init__.py | 35 | def _load_supertonic_pipeline(language: Any = None) -> Any: | CODE |
| LOW | plugins/supertonic/pipeline.py | 83 | def _parse_unsupported_characters(error: BaseException) -> list[str]: | CODE |
| LOW | plugins/supertonic/pipeline.py | 114 | def _remove_unsupported_characters(text: str, unsupported: Iterable[str]) -> str: | CODE |
| LOW | plugins/supertonic/pipeline.py | 123 | def _configure_supertonic_gpu() -> None: | CODE |
| LOW | tests/test_voice_utils.py | 16 | def test_empty_returns_fallback(self): | CODE |
| LOW | tests/test_voice_utils.py | 19 | def test_supertonic_uppercase(self): | CODE |
| LOW | tests/test_voice_utils.py | 39 | def test_formula_uses_fallback(self): | CODE |
| LOW | tests/test_voice_utils.py | 42 | def test_both_empty_uses_default(self): | CODE |
| LOW | tests/test_epub_heuristic_nav.py | 31 | def test_heuristic_nav_discovery(self): | CODE |
| LOW | tests/test_opds_import_metadata_mapping.py | 6 | def test_opds_metadata_overrides_maps_author_and_subtitle() -> None: | CODE |
| LOW | tests/test_opds_import_metadata_mapping.py | 29 | def test_opds_metadata_overrides_accepts_author_string() -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 108 | def test_plugin_loads_successfully(self, kokoro_plugin_dir: Path) -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 114 | def test_plugin_has_valid_manifest(self, kokoro_plugin_dir: Path) -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 123 | def test_plugin_has_model_requirements(self, kokoro_plugin_dir: Path) -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 129 | def test_plugin_manifest_capabilities(self, kokoro_plugin_dir: Path) -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 134 | def test_plugin_manifest_engine(self, kokoro_plugin_dir: Path) -> None: | CODE |
| LOW⚡ | tests/test_kokoro_plugin.py | 158 | def test_engine_satisfies_protocol(self, kokoro_plugin_dir: Path, host_context: HostContext) -> None: | CODE |
| LOW⚡ | tests/test_pronunciation.py | 34 | def test_skips_entries_without_pronunciation(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 40 | def test_skips_entries_without_token(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 46 | def test_deduplication_by_casefold(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 56 | def test_longer_token_sorted_first(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 67 | def test_normalized_fallback_to_entity_token(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 74 | def test_pattern_is_case_insensitive(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 82 | def test_non_mapping_items_skipped(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 115 | def test_skips_without_sentence(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 121 | def test_skips_without_choice(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 127 | def test_skips_when_no_matching_option(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 189 | def test_possessive_preserved(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 196 | def test_usage_counter_increments(self): | CODE |
| LOW⚡ | tests/test_pronunciation.py | 204 | def test_case_insensitive_match(self): | CODE |
| LOW | tests/test_pronunciation.py | 150 | def test_longer_sentence_sorted_first(self): | CODE |
| LOW | tests/test_pronunciation.py | 243 | def test_no_match_left_unchanged(self): | CODE |
| LOW | tests/test_pronunciation.py | 277 | def test_pronunciation_overrides_included(self): | CODE |
| LOW | tests/test_pronunciation.py | 293 | def test_manual_overrides_win(self): | CODE |
| LOW | tests/test_pronunciation.py | 311 | def test_speaker_entries_included(self): | CODE |
| LOW | tests/test_chunk_utils.py | 37 | def test_none_returns_default(self): | CODE |
| LOW | tests/test_chunk_utils.py | 42 | def test_garbage_returns_default(self): | CODE |
| LOW⚡ | tests/test_chunk_utils.py | 61 | def test_non_mapping_returns_empty(self): | CODE |
| LOW⚡ | tests/test_chunk_utils.py | 71 | def test_empty_dict_returns_empty(self): | CODE |
| LOW⚡ | tests/test_chunk_utils.py | 76 | def test_whitespace_only_returns_empty(self): | CODE |
| LOW | tests/test_chunk_utils.py | 110 | def test_fallback_token_from_normalized(self): | CODE |
| LOW | tests/test_chunk_utils.py | 118 | def test_handles_exception_gracefully(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 28 | def test_basic_override_by_index(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 38 | def test_override_by_source_title(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 46 | def test_disabled_override_skipped(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 54 | def test_metadata_updates_collected(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 62 | def test_no_matching_chapter_diagnostic(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 70 | def test_non_dict_override_skipped(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 76 | def test_text_from_base_when_not_provided(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 84 | def test_default_title_when_no_base(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 123 | def test_none_value_deletes_key(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 129 | def test_none_values_in_extracted_skipped(self): | CODE |
| LOW⚡ | tests/test_chapter_merge_normalize.py | 135 | def test_numeric_values_stringified(self): | CODE |
| LOW⚡ | tests/test_voice_formulas_pairs.py | 23 | def test_all_zero_returns_none(self): | CODE |
| LOW⚡ | tests/test_voice_formulas_pairs.py | 31 | def test_none_values_filtered(self): | CODE |
| LOW⚡ | tests/test_voice_formulas_pairs.py | 35 | def test_weight_normalization(self): | CODE |
| LOW | tests/test_epub_content_slicing.py | 31 | def test_single_file_multiple_chapters(self): | CODE |
| LOW | tests/test_chunk_text_for_tts_prefers_raw.py | 4 | def test_chunk_text_for_tts_prefers_text_over_normalized_text(): | CODE |
| LOW | tests/test_chunk_text_for_tts_prefers_raw.py | 15 | def test_chunk_text_for_tts_falls_back_to_original_text_then_normalized_text(): | CODE |
| LOW | tests/test_preview_applies_manual_overrides.py | 5 | def test_preview_applies_manual_override_before_normalization(monkeypatch): | CODE |
| 967 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 102 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 104 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 143 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 145 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 166 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 168 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 178 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_kokoro_plugin.py | 180 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/test_kokoro_plugin.py | 34 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/test_kokoro_plugin.py | 36 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/test_kokoro_plugin.py | 73 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/test_kokoro_plugin.py | 75 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/test_pronunciation.py | 9 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_pronunciation.py | 13 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_chunk_utils.py | 14 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_chunk_utils.py | 16 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chunk_utils.py | 53 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chunk_utils.py | 55 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chunk_utils.py | 82 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chunk_utils.py | 84 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_chapter_merge_normalize.py | 12 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_chapter_merge_normalize.py | 14 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chapter_merge_normalize.py | 92 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chapter_merge_normalize.py | 94 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chapter_merge_normalize.py | 142 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_chapter_merge_normalize.py | 144 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_output_paths.py | 146 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_output_paths.py | 148 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 16 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 18 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 52 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 54 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 76 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 78 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 91 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 93 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 113 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 115 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 222 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_output_paths.py | 224 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_domain_speaker_metadata.py | 86 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_domain_speaker_metadata.py | 88 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_domain_speaker_metadata.py | 263 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_domain_speaker_metadata.py | 265 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 15 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 17 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 212 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 214 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 471 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_domain_speaker_metadata.py | 473 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 116 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 118 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 157 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 159 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 180 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 182 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 192 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 194 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 235 | # ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_supertonic_plugin.py | 237 | # ────────────────────────────────────────────────────────────── | COMMENT |
| 163 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | build_pypi.py | 38 | CODE | |
| LOW | plugins/supertonic/__init__.py | 13 | CODE | |
| LOW | plugins/supertonic/engine.py | 7 | CODE | |
| LOW | plugins/supertonic/engine.py | 16 | CODE | |
| LOW | plugins/supertonic/engine.py | 17 | CODE | |
| LOW | plugins/supertonic/engine.py | 17 | CODE | |
| LOW | plugins/supertonic/pipeline.py | 8 | CODE | |
| LOW | plugins/kokoro/__init__.py | 13 | CODE | |
| LOW | plugins/kokoro/engine.py | 11 | CODE | |
| LOW | plugins/kokoro/engine.py | 19 | CODE | |
| LOW | plugins/kokoro/engine.py | 20 | CODE | |
| LOW | plugins/kokoro/engine.py | 20 | CODE | |
| LOW | tests/test_opds_import_metadata_mapping.py | 1 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 11 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 19 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 23 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 23 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 23 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 23 | CODE | |
| LOW | tests/test_kokoro_plugin.py | 40 | CODE | |
| LOW | tests/test_pronunciation.py | 3 | CODE | |
| LOW | tests/test_pronunciation.py | 5 | CODE | |
| LOW | tests/test_pronunciation.py | 6 | CODE | |
| LOW | tests/test_chunk_utils.py | 6 | CODE | |
| LOW | tests/test_chunk_utils.py | 11 | CODE | |
| LOW | tests/test_chapter_merge_normalize.py | 6 | CODE | |
| LOW | tests/test_chapter_merge_normalize.py | 8 | CODE | |
| LOW | tests/test_regression_webui_domain.py | 7 | CODE | |
| LOW | tests/test_output_paths.py | 6 | CODE | |
| LOW | tests/test_output_paths.py | 9 | CODE | |
| LOW | tests/test_output_paths.py | 11 | CODE | |
| LOW | tests/test_output_paths.py | 13 | CODE | |
| LOW | tests/test_domain_metadata_overrides.py | 3 | CODE | |
| LOW | tests/test_subtitle_generation.py | 3 | CODE | |
| LOW | tests/test_domain_normalization_pipeline.py | 5 | CODE | |
| LOW | tests/test_domain_normalization_pipeline.py | 6 | CODE | |
| LOW | tests/test_domain_pipeline_factory.py | 1 | CODE | |
| LOW | tests/test_service.py | 1 | CODE | |
| LOW | tests/test_domain_speaker_metadata.py | 7 | CODE | |
| LOW | tests/test_domain_speaker_metadata.py | 9 | CODE | |
| LOW | tests/test_domain_speaker_metadata.py | 9 | CODE | |
| LOW | tests/test_domain_speaker_metadata.py | 12 | CODE | |
| LOW | tests/test_domain_conversion_pipeline.py | 4 | CODE | |
| LOW | tests/test_domain_conversion_pipeline.py | 4 | CODE | |
| LOW | tests/test_domain_conversion_pipeline.py | 5 | CODE | |
| LOW | tests/test_domain_conversion_pipeline.py | 8 | CODE | |
| LOW | tests/test_domain_audio_buffer_extras.py | 4 | CODE | |
| LOW | tests/test_settings_integrations_secrets.py | 1 | CODE | |
| LOW | tests/test_settings_integrations_secrets.py | 3 | CODE | |
| LOW | tests/test_supertonic_plugin.py | 11 | CODE | |
| LOW | tests/test_supertonic_plugin.py | 19 | CODE | |
| LOW | tests/test_supertonic_plugin.py | 40 | CODE | |
| LOW | tests/test_split_pattern.py | 6 | CODE | |
| LOW | tests/test_audio_buffer.py | 4 | CODE | |
| LOW | tests/test_ffmetadata.py | 1 | CODE | |
| LOW | tests/test_epub_ncx_parsing.py | 10 | CODE | |
| LOW | tests/test_metadata_helpers_abs.py | 2 | CODE | |
| LOW | tests/test_metadata_helpers_abs.py | 125 | CODE | |
| LOW | tests/test_audiobookshelf_client.py | 1 | CODE | |
| LOW | tests/test_audio_helpers.py | 6 | CODE | |
| 331 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | build_pypi.py | 26 | except Exception: | CODE |
| LOW | plugins/supertonic/__init__.py | 135 | except Exception as e: | CODE |
| LOW | plugins/supertonic/engine.py | 145 | except Exception as e: | CODE |
| LOW | plugins/supertonic/pipeline.py | 95 | except Exception: | CODE |
| LOW | plugins/supertonic/pipeline.py | 141 | except Exception as exc: | CODE |
| LOW | plugins/supertonic/pipeline.py | 182 | except Exception as exc: # pragma: no cover | CODE |
| LOW | plugins/supertonic/pipeline.py | 269 | except Exception: | CODE |
| LOW | plugins/kokoro/__init__.py | 185 | except Exception as e: | CODE |
| LOW | plugins/kokoro/engine.py | 140 | except Exception as e: | CODE |
| LOW | tests/conftest.py | 14 | except Exception: | CODE |
| LOW | tests/conftest.py | 29 | except Exception: | CODE |
| LOW | tests/conftest.py | 36 | except Exception: | CODE |
| LOW | tests/test_preview_applies_manual_overrides.py | 55 | except Exception: | CODE |
| LOW | tests/__init__.py | 25 | except Exception: | CODE |
| LOW⚡ | tests/test_domain_audio_sink.py | 116 | except Exception: | CODE |
| LOW | tests/test_epub_missing_file_error_handling.py | 97 | except Exception as e: | CODE |
| LOW | abogen/spacy_utils.py | 54 | except Exception: | CODE |
| LOW | abogen/spacy_utils.py | 111 | except Exception as e: | CODE |
| LOW | abogen/spacy_utils.py | 117 | except Exception as e: | CODE |
| LOW | abogen/spacy_utils.py | 144 | except Exception: | CODE |
| LOW | abogen/is_nvidia.py | 7 | except Exception: | CODE |
| MEDIUM | abogen/is_nvidia.py | 4 | def check(): | CODE |
| LOW | abogen/pronunciation_store.py | 85 | except Exception: | CODE |
| MEDIUM | abogen/pronunciation_store.py | 19 | def _store_path() -> Path: | CODE |
| LOW | abogen/voice_profiles.py | 28 | except Exception: | CODE |
| MEDIUM | abogen/predownload_gui.py | 476 | def _check_kokoro_model(self) -> bool: | CODE |
| MEDIUM | abogen/predownload_gui.py | 489 | def _check_kokoro_config(self) -> bool: | CODE |
| LOW | abogen/predownload_gui.py | 40 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 100 | except Exception as exc: # pragma: no cover - best-effort reporting | CODE |
| LOW | abogen/predownload_gui.py | 111 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 137 | except Exception as exc: | CODE |
| LOW | abogen/predownload_gui.py | 148 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 168 | except Exception as exc: | CODE |
| LOW | abogen/predownload_gui.py | 192 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 198 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 224 | except Exception as exc: | CODE |
| LOW | abogen/predownload_gui.py | 471 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 486 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 499 | except Exception: | CODE |
| LOW | abogen/predownload_gui.py | 562 | except Exception: | CODE |
| LOW | abogen/word_substitution.py | 211 | except Exception: | CODE |
| MEDIUM | abogen/word_substitution.py | 206 | def replace_number(match): | CODE |
| MEDIUM | abogen/text_extractor.py | 547 | def _extract_cover(self) -> Tuple[Optional[bytes], Optional[str]]: | CODE |
| LOW⚡ | abogen/text_extractor.py | 457 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 466 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 473 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 480 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 491 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 498 | except Exception as exc: | CODE |
| LOW⚡ | abogen/text_extractor.py | 506 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 417 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 554 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 569 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 637 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 711 | except Exception: | CODE |
| LOW | abogen/text_extractor.py | 762 | except Exception as exc: | CODE |
| LOW | abogen/text_extractor.py | 899 | except Exception: | CODE |
| LOW | abogen/shutdown.py | 38 | except Exception: | CODE |
| LOW⚡ | abogen/shutdown.py | 52 | except Exception: | CODE |
| LOW⚡ | abogen/shutdown.py | 61 | except Exception: | CODE |
| 234 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | plugins/supertonic/pipeline.py | 44 | CODE | |
| LOW | plugins/supertonic/pipeline.py | 189 | CODE | |
| LOW | tests/test_epub_heuristic_nav.py | 31 | CODE | |
| LOW | tests/test_epub_content_slicing.py | 31 | CODE | |
| LOW | tests/test_epub_content_slicing.py | 118 | CODE | |
| LOW | tests/test_domain_normalization_pipeline.py | 268 | CODE | |
| LOW | tests/test_epub_standard_nav.py | 32 | CODE | |
| LOW | tests/test_epub_html_nav_parsing.py | 29 | CODE | |
| LOW | tests/test_epub_missing_file_error_handling.py | 36 | CODE | |
| LOW | tests/plugins/conftest.py | 23 | CODE | |
| LOW | abogen/voice_profiles.py | 15 | CODE | |
| LOW | abogen/predownload_gui.py | 521 | CODE | |
| LOW | abogen/text_extractor.py | 574 | CODE | |
| LOW | abogen/text_extractor.py | 655 | CODE | |
| LOW | abogen/subtitle_utils.py | 121 | CODE | |
| LOW | abogen/subtitle_utils.py | 229 | CODE | |
| LOW | abogen/subtitle_utils.py | 299 | CODE | |
| LOW | abogen/speaker_analysis.py | 479 | CODE | |
| LOW | abogen/heteronym_overrides.py | 201 | CODE | |
| LOW | abogen/utils.py | 322 | CODE | |
| LOW | abogen/utils.py | 466 | CODE | |
| LOW | abogen/utils.py | 502 | CODE | |
| LOW | abogen/llm_client.py | 129 | CODE | |
| LOW | abogen/check_cuda.py | 7 | CODE | |
| LOW | abogen/entity_analysis.py | 192 | CODE | |
| LOW | abogen/kokoro_text_normalization.py | 955 | CODE | |
| LOW | abogen/kokoro_text_normalization.py | 1630 | CODE | |
| LOW | abogen/kokoro_text_normalization.py | 1832 | CODE | |
| LOW | abogen/book_parser.py | 697 | CODE | |
| LOW | abogen/book_parser.py | 781 | CODE | |
| LOW | abogen/book_parser.py | 984 | CODE | |
| LOW | abogen/book_parser.py | 1035 | CODE | |
| LOW | abogen/tts_plugin/utils.py | 84 | CODE | |
| LOW | abogen/tts_plugin/loader.py | 112 | CODE | |
| LOW | abogen/tts_plugin/plugin_manager.py | 34 | CODE | |
| LOW | abogen/epub3/exporter.py | 81 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 221 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 243 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 274 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 377 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 612 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 1249 | CODE | |
| LOW | abogen/integrations/calibre_opds.py | 1375 | CODE | |
| LOW | abogen/integrations/audiobookshelf.py | 127 | CODE | |
| LOW | abogen/integrations/audiobookshelf.py | 208 | CODE | |
| LOW | abogen/integrations/audiobookshelf.py | 386 | CODE | |
| LOW | abogen/webui/service.py | 706 | CODE | |
| LOW | abogen/webui/routes/voices.py | 84 | CODE | |
| LOW | abogen/webui/routes/api.py | 247 | CODE | |
| LOW | abogen/webui/routes/main.py | 266 | CODE | |
| LOW | abogen/webui/routes/utils/form.py | 76 | CODE | |
| LOW | abogen/webui/routes/utils/form.py | 592 | CODE | |
| LOW | abogen/webui/routes/utils/form.py | 837 | CODE | |
| LOW | abogen/webui/routes/utils/settings.py | 68 | CODE | |
| LOW | abogen/webui/routes/utils/epub.py | 106 | CODE | |
| LOW | abogen/webui/routes/utils/epub.py | 206 | CODE | |
| LOW | abogen/application/conversion_planner.py | 87 | CODE | |
| LOW | abogen/application/conversion_planner.py | 164 | CODE | |
| LOW | abogen/application/conversion_executor.py | 147 | CODE | |
| LOW | abogen/infrastructure/subtitle_writer.py | 280 | CODE | |
| 46 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | plugins/supertonic/__init__.py | 115 | Create a SuperTonic engine instance. This function is the plugin entry point. It must be atomic: succeed fully | STRING |
| HIGH | plugins/kokoro/__init__.py | 150 | Create a Kokoro engine instance. This function is the plugin entry point. It must be atomic: succeed fully or r | STRING |
| HIGH | tests/plugins/conftest.py | 84 | Load a plugin and return its load result. This fixture loads the plugin using the loader, providing access to: | STRING |
| HIGH | abogen/tts_plugin/engine.py | 31 | Synthesize audio from text. Args: request: The synthesis request containing text, voice, parameters | STRING |
| HIGH | abogen/tts_plugin/capabilities.py | 23 | List available voices for a given source. Args: sourceId: The voice source identifier. Ret | STRING |
| HIGH | abogen/tts_plugin/capabilities.py | 45 | Generate a preview audio for a voice. Args: voice: Voice selection for the preview. tex | STRING |
| HIGH | abogen/tts_plugin/capabilities.py | 69 | Synthesize audio in streaming mode. Args: request: The synthesis request. Yields: | STRING |
| HIGH | abogen/tts_plugin/plugin.py | 39 | Create an engine instance. This is the factory function that creates an Engine from a plugin. It must b | STRING |
| HIGH | abogen/tts_plugin/plugin_manager.py | 88 | Create an engine instance for the given plugin. Args: plugin_id: The plugin identifier (e.g., "koko | STRING |
| HIGH | abogen/application/conversion_service.py | 35 | Execute a conversion request and return the result. This is the single entry point for both UIs. It orchestrates: | STRING |
| HIGH | abogen/application/conversion_planner.py | 31 | Build a complete conversion plan from a request. This is the single entry point that both UIs will call. It han | STRING |
| HIGH | abogen/application/conversion_executor.py | 156 | Execute a conversion plan and return the result. Args: plan: The conversion plan from build_conversion_plan | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | plugins/supertonic/engine.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | plugins/supertonic/pipeline.py | 17 | logger = logging.getLogger(__name__) | CODE |
| LOW | plugins/kokoro/engine.py | 30 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | abogen/predownload_gui.py | 425 | def _update_model_status(self, ok: bool) -> None: | CODE |
| LOW⚡ | abogen/predownload_gui.py | 432 | def _update_config_status(self, ok: bool) -> None: | CODE |
| LOW⚡ | abogen/predownload_gui.py | 439 | def _update_spacy_status(self, ok: bool, missing: List[str]) -> None: | CODE |
| LOW | abogen/predownload_gui.py | 266 | def _setup_ui(self) -> None: | CODE |
| LOW | abogen/predownload_gui.py | 413 | def _update_voices_status(self, ok: bool, missing: List[str]) -> None: | CODE |
| LOW | abogen/predownload_gui.py | 452 | def _set_status(self, key: str, text: str, color: str) -> None: | CODE |
| LOW | abogen/voice_formula_gui.py | 11 | __all__ = ["VoiceFormulaDialog"] | CODE |
| LOW | abogen/text_extractor.py | 22 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/shutdown.py | 144 | __all__ = ["register_shutdown", "request_shutdown", "register_cleanup"] | CODE |
| LOW | abogen/queue_manager_gui.py | 11 | __all__ = ["QueueManager"] | CODE |
| LOW | abogen/gui.py | 11 | __all__ = ["abogen"] | CODE |
| LOW | abogen/kokoro_text_normalization.py | 24 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/spacy_contraction_resolver.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/tts_plugin/__init__.py | 121 | __all__ = [ | CODE |
| LOW | abogen/epub3/__init__.py | 3 | __all__ = ["EPUB3PackageBuilder", "build_epub3_package"] | CODE |
| LOW | abogen/integrations/audiobookshelf.py | 15 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/webui/service.py | 742 | def _update_queue_positions_locked(self) -> None: | CODE |
| LOW | abogen/webui/__init__.py | 1 | __all__ = ["create_app"] | CODE |
| LOW | abogen/webui/routes/__init__.py | 9 | __all__ = [ | CODE |
| LOW | abogen/webui/routes/jobs.py | 31 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/webui/routes/main.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/application/integration_hooks.py | 34 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/application/cleanup.py | 68 | __all__ = [ | CODE |
| LOW | abogen/infrastructure/subtitle_writer.py | 362 | __all__ = [ | CODE |
| LOW | abogen/infrastructure/exporters.py | 23 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/infrastructure/exporters.py | 321 | __all__ = [ | CODE |
| LOW | abogen/domain/subtitle_processor.py | 32 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/domain/metadata_extraction.py | 16 | logger = logging.getLogger(__name__) | CODE |
| LOW | abogen/domain/conversion_pipeline.py | 22 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | abogen/pyqt/predownload_gui.py | 425 | def _update_model_status(self, ok: bool) -> None: | CODE |
| LOW⚡ | abogen/pyqt/predownload_gui.py | 432 | def _update_config_status(self, ok: bool) -> None: | CODE |
| LOW⚡ | abogen/pyqt/predownload_gui.py | 439 | def _update_spacy_status(self, ok: bool, missing: List[str]) -> None: | CODE |
| LOW | abogen/pyqt/predownload_gui.py | 266 | def _setup_ui(self) -> None: | CODE |
| LOW | abogen/pyqt/predownload_gui.py | 413 | def _update_voices_status(self, ok: bool, missing: List[str]) -> None: | CODE |
| LOW | abogen/pyqt/predownload_gui.py | 452 | def _set_status(self, key: str, text: str, color: str) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | build_pypi.py | 31 | # Check if build module is installed, install if not | COMMENT |
| LOW | tests/plugins/test_all_plugins.py | 195 | # Check if listVoices method exists | COMMENT |
| LOW | abogen/pronunciation_store.py | 43 | # Check if table exists | COMMENT |
| LOW | abogen/subtitle_utils.py | 156 | # Check if first line is timestamp | COMMENT |
| LOW | abogen/kokoro_text_normalization.py | 1937 | # Check if it really looks like a number (e.g. 1.05) | COMMENT |
| LOW | abogen/hf_tracker.py | 28 | if show_warning_signal_emitter: # Check if the emitter is set | CODE |
| LOW | abogen/book_parser.py | 258 | # Check if this page STARTS bookmarks | COMMENT |
| LOW | abogen/tts_plugin/loader.py | 223 | # Check if directory exists | COMMENT |
| LOW | abogen/tts_plugin/loader.py | 300 | # Check if any errors occurred | COMMENT |
| LOW | abogen/integrations/calibre_opds.py | 256 | # Check if it has a navigation link | COMMENT |
| LOW | abogen/integrations/calibre_opds.py | 327 | # Check if the server ignored the query and returned the default feed | COMMENT |
| LOW | abogen/integrations/calibre_opds.py | 1132 | # Check if all tokens match at least one fragment | COMMENT |
| LOW | abogen/domain/subtitle_generation.py | 197 | # Check if we've hit a sentence boundary or max words | COMMENT |
| LOW | abogen/pyqt/conversion.py | 410 | # Check if input is a subtitle file for additional configuration | COMMENT |
| LOW | abogen/pyqt/conversion.py | 461 | # Check if the input is a subtitle file or timestamp text file | COMMENT |
| LOW | abogen/pyqt/book_handler.py | 347 | # Check if content is already cached | COMMENT |
| LOW | abogen/pyqt/queue_manager_gui.py | 547 | # Read file content and calculate total_char_count using calculate_text_length | COMMENT |
| LOW⚡ | abogen/pyqt/gui.py | 2706 | # Check if path is a directory (for multiple chapter files) | COMMENT |
| LOW⚡ | abogen/pyqt/gui.py | 2722 | # Check if path exists and is a file before opening | COMMENT |
| LOW | abogen/pyqt/gui.py | 701 | # Check if text is empty based on character count | COMMENT |
| LOW | abogen/pyqt/gui.py | 710 | # Check if we need to warn about overwriting a non-temporary file | COMMENT |
| LOW | abogen/pyqt/gui.py | 1684 | # Check if this is a cache file | COMMENT |
| LOW | abogen/pyqt/gui.py | 1694 | # Check if this is a cache file | COMMENT |
| LOW | abogen/pyqt/gui.py | 1759 | # Check if current file is a subtitle file | COMMENT |
| LOW | abogen/pyqt/gui.py | 2436 | # Check if override was active (this determines which settings were ACTUALLY used) | COMMENT |
| LOW | abogen/pyqt/gui.py | 3231 | # Check if this is a timestamp detection (-1) or chapter detection | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_epub_content_slicing.py | 39 | # Create a single content file with two sections | COMMENT |
| MEDIUM | tests/test_conversion_executor_unified.py | 80 | # Create a fake segment object | COMMENT |
| MEDIUM | tests/test_epub_html_nav_parsing.py | 46 | # Create the Nav item manually to control the HTML structure exactly | COMMENT |
| MEDIUM | tests/plugins/test_all_plugins.py | 170 | # Create a minimal request (won't actually synthesize, just test error) | COMMENT |
| MEDIUM | tests/plugins/import_error/__init__.py | 8 | # The following code will never be reached, but is here for documentation | COMMENT |
| MEDIUM | tests/contracts/test_plugin_manager_contract.py | 153 | # Create a session by calling | COMMENT |
| MEDIUM | abogen/pyqt/voice_formula_gui.py | 441 | # Create main container layout with profile section and mixer section | STRING |
| MEDIUM | abogen/pyqt/voice_formula_gui.py | 1428 | # Create the profile with the new name | COMMENT |
| MEDIUM | abogen/pyqt/conversion.py | 1442 | # Create a unique filename based on voice_id, language, and speed | COMMENT |
| MEDIUM | abogen/pyqt/book_handler.py | 168 | # Create a centered loading overlay and show it while background load runs | COMMENT |
| MEDIUM | abogen/pyqt/gui.py | 3760 | # Create the directory if it doesn't exist | COMMENT |
| MEDIUM | abogen/pyqt/gui.py | 4148 | # Create a custom message box with checkbox | COMMENT |
| MEDIUM | abogen/pyqt/gui.py | 3797 | icon = target # Create a more direct PowerShell command | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/contracts/test_integration.py | 124 | # Step 1: Consumer gets plugin | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 127 | # Step 2: Plugin creates engine | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 132 | # Step 3: Engine creates session | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 137 | # Step 4: Session synthesizes | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 146 | # Step 5: Result returned | COMMENT |
| LOW | abogen/book_parser.py | 212 | # Step 1: Build the Skeleton Tree from TOC | COMMENT |
| LOW | abogen/book_parser.py | 238 | # Step 3: Add gap pages. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/contracts/test_integration.py | 124 | # Step 1: Consumer gets plugin | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 127 | # Step 2: Plugin creates engine | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 132 | # Step 3: Engine creates session | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 137 | # Step 4: Session synthesizes | COMMENT |
| LOW⚡ | tests/contracts/test_integration.py | 146 | # Step 5: Result returned | COMMENT |
| LOW | abogen/book_parser.py | 212 | # Step 1: Build the Skeleton Tree from TOC | COMMENT |
| LOW | abogen/book_parser.py | 238 | # Step 3: Add gap pages. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_domain_normalization_pipeline.py | 11 | """Tests for the comprehensive TTS text preparation pipeline.""" | STRING |
| LOW | abogen/integrations/calibre_opds.py | 1450 | # Only add if not found elsewhere? Or just add small amount? | COMMENT |
| LOW⚡ | abogen/webui/routes/api.py | 588 | # For now, just use base settings as in original code (presumably) | COMMENT |
| LOW | abogen/infrastructure/subtitle_writer.py | 240 | # For now, just return the text with the highlight color | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_title_builder.py | 23 | result = build_title_intro_text({"title": "My Book", "author": "John Doe"}, "book.epub") | CODE |
| LOW | tests/test_title_builder.py | 49 | result = build_outro_text({"author": "John Doe"}, "book.epub") | CODE |
| LOW | tests/test_title_builder.py | 53 | result = build_outro_text({"title": "My Book", "author": "John Doe"}, "book.epub") | CODE |
| LOW | tests/test_metadata_helpers.py | 50 | assert format_author_sentence("John Doe") == "By John Doe" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | abogen/infrastructure/exporters.py | 316 | CODE | |
| MEDIUM | abogen/infrastructure/exporters.py | 318 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | abogen/kokoro_text_normalization.py | 289 | CODE | |
| LOW | abogen/webui/service.py | 351 | CODE | |
| LOW | abogen/domain/subtitle_processor.py | 146 | CODE | |
| LOW | abogen/domain/conversion_pipeline.py | 278 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | docker-compose.yaml | 6 | # Usage: | COMMENT |
| LOW | docker-compose.webui.yml | 6 | # Usage: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | docker-compose.yaml | 1 | # Docker Compose for Abogen | COMMENT |
| LOW | docker-compose.yaml | 61 | # Runtime flag is only honored by legacy docker-compose (v1) CLI. | COMMENT |
| LOW | docker-compose.webui.yml | 1 | # Docker Compose for Abogen Web UI (Flask-based interface) | COMMENT |