Coverage for sources/librovore/structures/sphinx/detection.py: 25%
43 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 21:59 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 21:59 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21''' Sphinx detection and metadata extraction. '''
24from urllib.parse import ParseResult as _Url
26from . import __
27from . import extraction as _extraction
28from . import urls as _urls
31_scribe = __.acquire_scribe( __name__ )
34class SphinxDetection( __.StructureDetection ):
35 ''' Detection result for Sphinx documentation sources. '''
37 source: str
38 has_searchindex: bool = False
39 normalized_source: str = ''
40 theme: __.typx.Optional[ str ] = None
42 @classmethod
43 async def from_source(
44 selfclass,
45 auxdata: __.ApplicationGlobals,
46 processor: __.Processor,
47 source: str,
48 ) -> __.typx.Self:
49 ''' Constructs detection from source location. '''
50 detection = await processor.detect( auxdata, source )
51 return __.typx.cast( __.typx.Self, detection )
53 async def extract_contents(
54 self,
55 auxdata: __.ApplicationGlobals,
56 source: str,
57 objects: __.cabc.Sequence[ __.InventoryObject ], /,
58 ) -> tuple[ __.ContentDocument, ... ]:
59 ''' Extracts documentation content for specified objects. '''
60 theme = self.theme if self.theme is not None else __.absent
61 documents = await _extraction.extract_contents(
62 auxdata, source, objects, theme = theme )
63 return tuple( documents )
67async def check_searchindex(
68 auxdata: __.ApplicationGlobals, source: _Url
69) -> bool:
70 ''' Checks if searchindex.js exists (indicates full Sphinx site). '''
71 url = _urls.derive_searchindex_url( source )
72 return await __.probe_url( auxdata.probe_cache, url )
75async def detect_theme(
76 auxdata: __.ApplicationGlobals, source: _Url
77) -> dict[ str, __.typx.Any ]:
78 ''' Detects Sphinx theme and other metadata. '''
79 theme_metadata: dict[ str, __.typx.Any ] = { }
80 html_url = _urls.derive_html_url( source )
81 try:
82 # TODO: Use probe_url instead of `try`.
83 html_content = await __.retrieve_url_as_text(
84 auxdata.content_cache,
85 html_url, duration_max = 10.0 )
86 except __.DocumentationInaccessibility: pass
87 else:
88 html_content_lower = html_content.lower( )
89 if ( 'furo' in html_content_lower
90 or 'css/furo.css' in html_content_lower
91 ): theme_metadata[ 'theme' ] = 'furo'
92 elif ( 'sphinx_rtd_theme' in html_content_lower
93 or 'css/theme.css' in html_content_lower
94 ): theme_metadata[ 'theme' ] = 'sphinx_rtd_theme'
95 elif ( 'alabaster' in html_content_lower
96 or 'css/alabaster.css' in html_content_lower
97 ): theme_metadata[ 'theme' ] = 'alabaster'
98 elif ( 'pydoctheme.css' in html_content_lower
99 or 'classic.css' in html_content_lower
100 ): theme_metadata[ 'theme' ] = 'pydoctheme'
101 elif 'flask.css' in html_content_lower:
102 theme_metadata[ 'theme' ] = 'flask'
103 elif 'css/nature.css' in html_content_lower:
104 theme_metadata[ 'theme' ] = 'nature'
105 elif 'css/default.css' in html_content_lower:
106 theme_metadata[ 'theme' ] = 'classic'
107 elif 'sphinx_book_theme' in html_content_lower:
108 theme_metadata[ 'theme' ] = 'sphinx_book_theme'
109 elif 'pydata_sphinx_theme' in html_content_lower:
110 theme_metadata[ 'theme' ] = 'pydata_sphinx_theme'
111 # If no theme detected, don't set theme key (returns None)
112 return theme_metadata