Coverage for / var / devmt / py / ghmdlib_0.1.0 / ghmdlib / libs / _online.py: 100%
21 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-05 11:41 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-05 11:41 +0000
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""
4:Purpose: This module provides the functionality for **online**
5 conversions.
7:Platform: Linux/Windows | Python 3.10+
8:Developer: J Berendt
9:Email: development@s3dev.uk
11:Comments: This module is designed for internal use only.
13"""
14# pylint: disable=line-too-long # _CSS_URI and _CSS_LINK (only)
16import json
17import logging
18import requests
20logger = logging.getLogger(__name__)
23class Online:
24 """This class provides the functions used for online conversions.
26 Specifically, this class employs requests to GitHub to obtain the
27 CSS and calls to the GitHub API for Markdown conversion.
29 """
31 _CSS_LINK = '<link rel=\"stylesheet\" href=\"{uri}\" crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\" />'
32 _CSS_URI = 'https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.8.1/github-markdown-{theme}.min.css'
33 _TIMEOUT = 5
35 @classmethod
36 def convert(cls, content: str, headers: str, mode: str) -> str:
37 """Convert Markdown file(s) to HTML.
39 Args:
40 content (str): Markdown file content to be converted.
41 headers (str): Headers to be send in the HTTP request.
42 mode (str): Mode to be used for the conversion.
44 Returns:
45 str: A string containing the Markdown content converted to
46 HTML.
48 """
49 resp = requests.post('https://api.github.com/markdown',
50 headers=headers,
51 data=json.dumps({'text': content, 'mode': mode}),
52 timeout=cls._TIMEOUT)
53 logger.debug('API response: %s', resp)
54 if resp.status_code != 200: # nocover
55 msg = 'An error occurred while converting through the GitHub API.'
56 raise RuntimeError(msg)
57 return resp.text
59 @classmethod
60 def set_css(cls, theme: str, embed_css: bool, raw: bool=False) -> str:
61 """Get and set the CSS for the HTML output.
63 Args:
64 theme (str): Theme to be used (dark | light).
65 embed_css (bool): Embed the CSS rather than linking.
66 raw (bool, optional): Return the raw CSS content, as
67 downloaded. This *excludes* the ``<style>`` tag wrapper.
68 Defaults to False.
70 Raises:
71 ValueError: If the CSS could not be retrieved.
73 Returns:
74 str: A string containing either the CSS for the desired
75 theme, or a link; depending on whether the ``embed_css``
76 argument is True or False, respectively.
78 """
79 css_uri = cls._CSS_URI.format(theme=theme)
80 if embed_css:
81 resp = requests.get(css_uri, timeout=cls._TIMEOUT)
82 if resp.status_code != 200: # nocover
83 msg = ('Could not retrieve CSS. Check your internet connection or try without '
84 '--embed-css.')
85 raise RuntimeError(msg)
86 css = f'<style>{resp.text}</style>' if not raw else resp.text
87 else:
88 css = cls._CSS_LINK.format(uri=css_uri)
89 return css