def page_context_handler(app, pagename, templatename, context, doctree): import git global g if g is None: # We have already errored about this pass fullpagename = pagename if not app.confdir else os.path.join( app.confdir, pagename) # Don't barf on "genindex", "search", etc if not os.path.isfile("%s.rst" % fullpagename): return try: commits = g.iter_commits('--all', max_count=1, paths="%s.rst" % fullpagename) if not commits: # Don't datestamp generated rst's (e.g. imapd.conf.rst) # Ideally want to check their source - lib/imapoptions, etc, but # that involves getting the source/output pair into the extension. return commit = next(iter(commits)) context['gitstamp'] = datetime.datetime.fromtimestamp( commit.authored_date).strftime("%Y‑%m‑%d") user = GHCachedUser(commit.author.name) if 'gh' in globals(): # Look in cache first to avoid spamming GitHub if commit.author.email in gh_user_cache: user = gh_user_cache[commit.author.email] else: # Search GitHub and retrieve first user with matching email (if any) gh_users = gh.search_users(commit.author.email) if gh_users.totalCount: gh_user = next(iter(gh_users)) user.name = gh_user.name user.login = gh_user.login user.avatar_url = gh_user.avatar_url else: # Try searching the commit hash instead gh_commit = gh_repo.get_commit(commit.hexsha) if gh_commit: user.name = gh_commit.author.name user.login = gh_commit.author.login user.avatar_url = gh_commit.author.avatar_url gh_user_cache[commit.author.email] = user context['gitauthor'] = user.name context['gitlogin'] = user.login context['gitavatar'] = user.avatar_url except git.exc.GitCommandError: # File doesn't exist or something else went wrong. raise errors.ExtensionError("Can't fetch git history for %s.rst." % fullpagename) except StopIteration: print("File not under source control yet.")
def builder_inited(app): app.info('In: ' + os.path.abspath('.')) source_dir = app.srcdir build_dir = app.outdir app.info('Generating devtest from %s into %s' % (source_dir, build_dir)) ret = os.system('scripts/extract-docs') if ret: raise errors.ExtensionError("Error generating %s/devtest.rst" % build_dir)
def what_build_am_i(app): global g if app.builder.format != 'html': return try: import git except ImportError: raise errors.ExtensionError( "gitpython package not installed. Required to generate html. Please run: pip install gitpython" ) try: global g g = git.Repo('.') except Exception: print( "gitstamp extension enabled, but no git repository found. No git datestamps will be generated." ) else: app.connect('html-page-context', page_context_handler) try: global gh global gh_repo global gh_user_cache token = os.getenv('GITHUB_ACCESS_TOKEN') if token: gh = Github(token) gh_repo = gh.get_repo('symbol/symbol-docs') gh_user_cache = {} else: raise errors.ExtensionError( "Missing GITHUB_ACCESS_TOKEN environment variable.") except Exception as e: print(e) print( "gitstamp extension enabled, but GitHub link failed. No GH links will be generated." )
def visit_literal_block(self, node): """Visit a ``literal_block`` node. This verifies the state of each literal / code block. """ language = node.attributes.get('language', '') test_type = node.attributes.get('testnodetype', '') if test_type != 'doctest': if language.lower() in ('', 'python'): msg = _LITERAL_ERR_TEMPLATE.format( node.rawsource, language, test_type) raise errors.ExtensionError(msg) # The base classes are not new-style, so we can't use super(). return html.SmartyPantsHTMLTranslator.visit_literal_block(self, node)
def page_context_handler(app, pagename, templatename, context, doctree): import git global g if g is None: # We have already errored about this pass fullpagename = pagename docsrc = '' try: docsrc = app.confdir + "/" if docsrc != "/": fullpagename = docsrc + pagename except KeyError: pass # Don't barf on "genindex", "search", etc if not os.path.isfile("%s.rst" % fullpagename): return try: updated = g.log('--pretty=format:%ai', '-n 1', "%s.rst" % fullpagename) updated = updated[:10] if updated == "": # Don't datestamp generated rst's (e.g. imapd.conf.rst) # Ideally want to check their source - lib/imapoptions, etc, but # that involves getting the source/output pair into the extension. return context['gitstamp'] = datetime.datetime.strptime( updated, "%Y-%m-%d").strftime(app.config.gitstamp_fmt) except git.exc.GitCommandError: # File doesn't exist or something else went wrong. raise errors.ExtensionError("Can't fetch git history for %s.rst." % fullpagename) except ValueError: # Datestamp can't be parsed. app.info("%s: Can't parse datestamp () %s ) for gitstamp, output \ won't have last updated time." % (pagename, updated)) pass
def what_build_am_i(app): global g if (app.builder.format != 'html'): return try: import git except ImportError as e: raise errors.ExtensionError(f"""Unable to import gitpython. \ Required to generate html. You may need to run: pip install gitpython. The error was: {e} """) try: global g g = git.Git('.') except BaseException: app.info(sys.exc_info()[0]) app.warn("gitstamp extension enabled, but no git repository found. No \ git datestamps will be generated.") else: app.connect('html-page-context', page_context_handler)
def what_build_am_i(app): global g if (app.builder.format != 'html'): return try: import git except ImportError: raise errors.ExtensionError( "gitpython package not installed. Required to generate html. Please run: pip install gitpython" ) try: global g g = git.Git('.') except: app.info(sys.exc_info()[0]) app.warn( "gitstamp extension enabled, but no git repository found. No git datestamps will be generated." ) else: app.add_config_value('gitstamp_fmt', "%b %d %Y", 'html') app.connect('html-page-context', page_context_handler)
def generate_sitemap(app, exception): if exception: return urls = [] website = app.config.sitemap_website if website is None: raise errors.ExtensionError( "Cannot generate sitemap. Set 'sitemap_website' in conf.py with website hostname" ) env = app.builder.env for page in env.found_docs: for site in website: url = {} url["loc"] = "{}{}.html".format(site, page) # If we can deduce last modified time from gitstamp, # then we can publish this here. # url["lastmod"] = ... urls.append(url) urlset = xml.etree.ElementTree.Element("urlset", {"xmlns": namespace}) for url in urls: url_element = xml.etree.ElementTree.SubElement(urlset, "url") loc = xml.etree.ElementTree.SubElement(url_element, "loc") loc.text = url["loc"] if "lastmod" in url: lastmod = xml.etree.ElementTree.SubElement(url_element, "lastmod") lastmod.text = url["lastmod"] tree = xml.etree.ElementTree.ElementTree(urlset) tree.write(os.path.join(app.outdir, "sitemap.xml"), "UTF-8", True)