txoo 0.10.0

A Bitcoin transaction-output oracle
Documentation
#!/usr/bin/env python3

#! /usr/bin/env python3
import os
import re
import sys

import yaml
from datetime import datetime
from jinja2 import Template

# Define the template for the HTML file
html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Attestation Data</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        table {
            width: 80%;
            border-collapse: collapse;
            margin-bottom: 20px;
        }
        th, td {
            border: 1px solid black;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        td {
            font-family: 'Courier New', monospace;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <h2>About</h2>
    See the <a href="https://gitlab.com/lightning-signer/txoo">TXOO repo</a> for more information.
    
    <p style="font-size: 8px">Generated at {{ now }}</p>
    
    <h2>Oracle Configuration</h2>
    <div>
        <p>network: {{ config["network"] }}</p>
        <p>start_block: {{ config["start_block"] }}</p>
        <p>public_key: {{ config["public_key"] }}</p>
    </div>
    <h2>Attestation Data</h2>
    <table>
        <thead>
            <tr>
            <th>Block Hash</th>
            <th>Block Height</th>
            <th>Filter Header</th>
            <th>Timestamp</th>
            </tr>
        </thead>
        <tbody>
            {% for row in rows %}
                <tr>
                    <td><a href="{{ row['filename'] }}">{{ row['block_hash'] }}</a></td>
                    <td>{{ row['block_height'] }}</td>
                    <td>{{ row['filter_header'] }}</td>
                    <td>{{ row['time'] }}</td>
                    <td><a href="https://blockstream.info/{{ config["network"] }}/block/{{ row['block_hash'] }}">Explorer</a></td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>
"""


def process_file(file_path):
    with open(file_path, "r") as f:
        data = yaml.safe_load(f)

    # Convert the Unix timestamp in the "time" field to a datetime object in ISO format
    data = data["attestation"]
    timestamp = int(data["time"])
    data["time"] = datetime.utcfromtimestamp(timestamp).isoformat(sep=" ", timespec="seconds")

    return data


def main(dir_path):
    output_file_path = os.path.join(dir_path, "index.html")
    file_pattern = re.compile(r"\d+-[0-9a-f]+\.sa$")
    rows = []

    with open(os.path.join(dir_path, "config"), "r") as f:
        config = yaml.safe_load(f)

# filter and sort the files
    files = [f for f in os.listdir(dir_path) if file_pattern.match(f)]
    files.sort(key=lambda f: int(f.split("-")[0]), reverse=True)
    for file_name in files:
        if file_pattern.match(file_name):
            file_path = os.path.join(dir_path, file_name)
            row = process_file(file_path)
            row['filename'] = file_name
            rows.append(row)

    now = datetime.now().isoformat(sep=" ", timespec="seconds")
    if rows:
        template = Template(html_template)
        html_content = template.render(rows=rows, config=config, now=now)

        with open(output_file_path, "w") as f:
            f.write(html_content)
    else:
        print("No matching files found.")


if __name__ == "__main__":
    main(sys.argv[1])