aboutsummaryrefslogtreecommitdiffstats
path: root/app/server.py
blob: 038760e8d0c2895530f1e814c3bfa0fc40d466de (plain)
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
113
114
115
116
117
118
from typing import Any, cast
import bottle
from tinydb import Query

from app.DatabaseManager import database_manager


def feed_id_to_td(feed_id: str) -> str:
    return f'<td><a href="/{feed_id}">{feed_id}</a></td>'


def feed_last_build_date_to_td(last_build_date: str) -> str:
    return f"<td>{last_build_date}</td>"


def feed_to_tr(feed: dict[str, str]) -> str:
    return f'<tr>{feed_id_to_td(feed["feed_id"])}{feed_last_build_date_to_td(feed.get("feed_last_build_date", ""))}</tr>'


def feeds_to_table(feeds: list[dict[str, str]]) -> str:
    if len(feeds) == 0:
        return (
            "No feeds (yet). Add feeds by defining them in your Aggrofile. "
            + "If you did that already, you might have to wait a bit for the data to propagate."
        )

    trs: list[str] = [feed_to_tr(feed) for feed in feeds]
    thead = f"<thead><tr><td>Feed</td><td>Last build date</td></tr></thead>"
    tbody = f'<tbody>{"".join(trs)}</tbody>'
    return "<table>" + thead + tbody + "</table>"


@bottle.route("/")
def index():
    if database_manager.db is None:
        raise Exception("Database is not initialized")

    Q = Query()
    _feeds = database_manager.feeds.all()
    feeds = cast(list[dict[str, str]], _feeds)

    bottle.response.set_header("content-type", "text/html")
    page = f"""
    <html lang="en">
    <head>
    <title>Aggro &ndash; Feed manipulator</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
    body {{
        font-family: Open Sans, Arial;
        color: #050505;
        font-size: 16px;
        margin: 2em auto;
        max-width: 800px;
        padding: 1em;
        line-height: 1.4;
        text-align: justify;
    }}
    h1 {{
        margin-bottom: 0;
    }}
    table {{
        width: 100%;
        border-collapse: collapse;
    }}

    table, th, td {{
        border: 1px solid #e0e0e0;
    }}

    th, td {{
        padding: 8px;
    }}

    footer {{
        margin-top: 32px;
    }}
    </style>
    </head>
    <body>
        <h1>Aggro</h2>
        <i>Feed manipulator</i>
        <h2>Feeds served at this address</h2>
        {feeds_to_table(feeds)}
        <footer>
        <p>
        <a href="https://github.com/jantuomi/aggro">Aggro</a> is MIT licensed open source software.
        </p>
        </footer>
    </body>
    </html>
    """

    return page


@bottle.route("/<feed_id>")
def feed(feed_id: str):
    if database_manager.db is None:
        raise Exception("Database is not initialized")

    Q = Query()
    res = database_manager.feeds.search(Q.feed_id == feed_id)
    if len(res) == 0:
        bottle.abort(400, f"No feed found with id {feed_id}")

    if len(res) > 1:
        bottle.abort(400, f"Weird number of feeds found with id {feed_id}: {len(res)}")

    bottle.response.set_header("content-type", "application/xml")

    feed: Any = res[0]
    feed_xml: str = feed["feed_xml"]
    return feed_xml


def run_web_server(host: str, port: int):
    bottle.run(host=host, port=port)