boop.py 5.06 KB
Newer Older
1
2
3
#!/bin/env python3

import os
4
import sys
5
import distutils.dir_util
6
import locale
7

8
9
10
import boop.environment as environment
import boop.configuration as config
import boop.utils as utils
berumuron's avatar
berumuron committed
11
from boop.feed import Feed
12
13


14
locale.setlocale(locale.LC_ALL, "")
15

16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class ProgramError(Exception):
    """Exception raised during the program execution.

    Examples:

    >>> try:
    ...     raise ProgramError("Oops")
    ... except ProgramError as e:
    ...     print(e.args[0])
    Oops
    """

    pass


32
def main(environment):
berumuron's avatar
berumuron committed
33
34
    # Make sure ./_site folder is empty
    output_path = os.path.join(os.curdir, "_site")
35
    utils.init_output_folder(output_path)
36
37
38

    # Load the configuration (it can be overidden by a configuration.yml file)
    configuration_path = os.path.join(os.curdir, "configuration.yml")
39
    configuration = config.load(configuration_path, environment, output_path)
40

41
    # STEP 1: we load all the Articles, Pages and Feeds
42
    pages = []
43
    series = []
44
    articles = []
45
    feeds = []
46
47

    # Check that index file exists
48
49
50
    index_filepath = os.path.join(os.curdir, "index.html")
    if not os.path.exists(index_filepath):
        raise ProgramError("./index.html file does not exist")
51

52
53
54
55
    index_page = utils.build_page_from_filepath(
        index_filepath, configuration, basename=os.curdir
    )
    pages.append(index_page)
56
57

    # Check that pages directory exists and load Pages from it
berumuron's avatar
berumuron committed
58
59
    pages_path = os.path.join(os.curdir, "pages")
    if os.path.isdir(pages_path):
60
        for filename in utils.dir_tree(pages_path, only=["html"]):
berumuron's avatar
berumuron committed
61
            page_filepath = os.path.join(pages_path, filename)
62
63
64
65
            page = utils.build_page_from_filepath(
                page_filepath, configuration, basename=pages_path
            )
            pages.append(page)
66

67
68
69
    # Check that articles directory exists and load Articles from it
    articles_path = os.path.join(os.curdir, "articles")
    if os.path.isdir(articles_path):
70
        dirs_with_articles = list(utils.list_dirs(articles_path)) + ["."]
71
72
73
        for dirname in dirs_with_articles:
            dirpath = os.path.realpath(os.path.join(articles_path, dirname))

74
75
            serie_filepath = os.path.join(dirpath, "serie.html")
            serie = None
76
77
78

            # If the directory contains a `serie.html` file, it means it
            # contains a serie so we load a page from it.
79
            if dirname != "." and os.path.exists(serie_filepath):
80
                slug = f"serie/{dirname}"
81
82
83
                serie = utils.build_page_from_filepath(
                    serie_filepath, configuration, slug=slug
                )
84
                series.append(serie)
berumuron's avatar
berumuron committed
85

86
87
            # Let's collect all the articles from the directory
            serie_articles = []
88
            for filename in utils.list_files(dirpath, only=["md"]):
89
                article_filepath = os.path.join(dirpath, filename)
90
                article = utils.build_article_from_filepath(
91
92
93
                    article_filepath, configuration, serie
                )
                articles.append(article)
94
95
96
                serie_articles.append(article)

            # If the directory contains a serie and there is at least one
97
98
            # article, we load a feed for the serie and we let know the serie
            # about its articles and feed.
99
100
101
102
103
104
105
106
107
108
            if serie and serie_articles:
                feed_slug = f"feeds/{dirname}"
                feed_title = f"{serie.title()} - {configuration['SITE_TITLE']}"
                serie_feed = Feed(
                    feed_slug,
                    serie_articles,
                    {"title": feed_title, "site_link": serie.url()},
                    configuration=configuration,
                )
                feeds.append(serie_feed)
109

110
111
112
                serie.set_articles(serie_articles)
                serie.set_feed(serie_feed)

berumuron's avatar
berumuron committed
113
114
115
    # Load a "blog" page which has access to the list of articles
    blog_template_filepath = os.path.join("templates", "blog.html")
    if os.path.exists(blog_template_filepath):
116
        blog_page = utils.build_blog_page(articles, series, configuration)
berumuron's avatar
berumuron committed
117
118
        pages.append(blog_page)

119
    # And load the main feed
120
    if len(articles) > 0:
berumuron's avatar
berumuron committed
121
122
        feed = Feed("feeds/all", articles, configuration=configuration)
        feeds.append(feed)
123

124
    # STEP 2: we write all the pages, articles and feeds
125
    for page in pages + series:
126
127
128
129
130
131
132
        utils.write_content(page, output_path)
        print(f"Written page: {page.url()}")

    for article in articles:
        utils.write_content(article, output_path)
        print(f"Written article: {article.url()}")

133
134
135
    for feed in feeds:
        utils.write_feed(feed, output_path)
        print(f"Written feed: {feed.url()}")
berumuron's avatar
berumuron committed
136

137
    # STEP 3: and we finish by copying the static folder.
138
139
140
141
    static_dirpath = os.path.join(os.curdir, "static")
    if os.path.isdir(static_dirpath):
        distutils.dir_util.copy_tree(static_dirpath, output_path)
        print(f"Static files copied")
142

143
144

if __name__ == "__main__":
145
    environment = environment.load_from_argv(sys.argv)
146
    try:
147
        main(environment)
148
149
150
        print("Boop!")
    except ProgramError as e:
        print(e.args[0], file=sys.stderr)