aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/content/utils.py
blob: a89db83cae8e5e50c5a5969513b78f35d2bb734d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import os
from typing import Dict, List, Optional, Union

import requests
import yaml
from dateutil import parser
from django.conf import settings
from django.http import Http404
from markdown2 import markdown

COMMITS_URL = "https://api.github.com/repos/{owner}/{name}/commits?path={path}&sha={branch}"
BASE_ARTICLES_LOCATION = "pydis_site/apps/content/resources/content/"


def get_category(path: List[str]) -> Dict[str, str]:
    """Load category information by name from _info.yml."""
    path = settings.ARTICLES_PATH.joinpath(*path)
    if not path.exists() or not path.is_dir():
        raise Http404("Category not found.")

    return yaml.safe_load(path.joinpath("_info.yml").read_text())


def get_categories(path: Optional[List[str]] = None) -> Dict[str, Dict]:
    """Get all categories information."""
    categories = {}
    if path is None:
        categories_path = settings.ARTICLES_PATH
        path = []
    else:
        categories_path = settings.ARTICLES_PATH.joinpath(*path)

    for name in categories_path.iterdir():
        if name.is_dir():
            categories[name.name] = get_category([*path, name.name])

    return categories


def get_articles(path: Optional[List[str]] = None) -> Dict[str, Dict]:
    """Get all root or category articles."""
    if path is None:
        base_dir = settings.ARTICLES_PATH
    else:
        base_dir = settings.ARTICLES_PATH.joinpath(*path)

    articles = {}

    for item in base_dir.iterdir():
        if item.is_file() and item.name.endswith(".md"):
            md = markdown(item.read_text(), extras=["metadata"])
            articles[os.path.splitext(item.name)[0]] = md.metadata

    return articles


def get_article(path: List[str]) -> Dict[str, Union[str, Dict]]:
    """Get one specific article. When category is specified, get it from there."""
    article_path = settings.ARTICLES_PATH.joinpath(*path[:-1])

    # We need to include extension MD
    article_path = article_path.joinpath(f"{path[-1]}.md")
    if not article_path.exists() or not article_path.is_file():
        raise Http404("Article not found.")

    html = markdown(
        article_path.read_text(),
        extras=[
            "metadata",
            "fenced-code-blocks",
            "header-ids",
            "strike",
            "target-blank-links",
            "tables",
            "task_list"
        ]
    )

    return {"article": str(html), "metadata": html.metadata}


def get_github_information(
        path: List[str]
) -> Dict[str, Union[List[str], str]]:
    """Get article last modified date and contributors from GitHub."""
    result = requests.get(
        COMMITS_URL.format(
            owner=settings.SITE_REPOSITORY_OWNER,
            name=settings.SITE_REPOSITORY_NAME,
            branch=settings.SITE_REPOSITORY_BRANCH,
            path=(
                f"{BASE_ARTICLES_LOCATION}{'/'.join(path[:-1])}"
                f"{'/' if len(path) > 1 else ''}{path[-1]}.md"
            )
        )
    )

    if result.status_code == 200 and len(result.json()):
        data = result.json()
        return {
            "last_modified": parser.isoparse(
                data[0]["commit"]["committer"]["date"]
            ).strftime("%dth %B %Y"),
            "contributors": {
                c["commit"]["committer"]["name"]: c["committer"]["html_url"] for c in data
            }
        }
    else:
        return {
            "last_modified": "N/A",
            "contributors": {}
        }