Collection of themes/skins for the Fossil SCM

โŒˆโŒ‹ โŽ‡ branch:  Fossil Skins Extra


Artifact [328f5bb90d]

Artifact 328f5bb90d3447a1ded7a63fcea7ed1ba3a94549:

  • Executable file extroot/fx_meta — part of check-in [18aea61ba2] at 2022-01-21 21:30:50 on branch trunk — Support technotes (user: mario size: 4779)

#!/usr/bin/php-cgi -dcgi.force_redirect=0
<?php
# encoding: utf-8
# api: cgi
# type: store
# category: template
# title: fx_meta cache
# description: Prepare twitter tags for wiki + doc pages
# version: 0.6
# state: alpha
# config:
#    { name: project-twitter, type: str, value: "", description: "Twitter handle for project (e.g. @sqlite1)" }
# access: admin
#
# Crafts a `fx_meta` database table to prepare twitter previews
# and image links, or other <meta> and <link> fields.
# Which can then be embedded into the header via:
#
#   <th1>  catch { query {SELECT meta FROM fx_meta WHERE name = $current_page} { html $meta } }  </th1>
#
# ยท Should be useable as extroot/ hook.
# ยท As cron script it would require supplying the repository file, and setting
#   SERVER_NAME and FOSSIL_URI env vars.
# ยท Possibly should adapt twitter:site (or remove if the skin already contains it)
#
# File links shouldn't be generated statically though. There's `file_link.th1` now
# as auxiliary feature.
#   <th1> catch { file_link } </th1>
# Will output the vcs-raw links instead.
#


#-- config
error_reporting(E_ALL);
ini_set("display_errors", 1);
define("PROJECT_TWITTER", "sqlite1");  # if not via extra config
include("./fossil_common.php");

#-- cli or admin usage
if (!empty($_SERVER["argv"][1])) {
    $_SERVER["FOSSIL_REPOSITORY"] = $_SERVER["argv"][1];
}
elseif (!is_admin()) {
    die("Run as cron, or as admin");
}
putenv("GATEWAY_INTERFACE=");
putenv("REQUEST_URI=");
putenv("SCRIPT_FILENAME=");
ini_set("display_errors", 1);



# INSERT
function insert_meta($name, $meta) {
   db(
        "INSERT INTO fx_meta (`name`, `meta`) VALUES (?, ?);",
        [$name, $meta]
    );
}

#-- init
db("CREATE TABLE IF NOT EXISTS fx_meta (name TEXT, meta TEXT)");
db("DELETE FROM fx_meta");
wiki_pages();
doc_pages();
wiki_event();


#-- loop through pages
function wiki_pages($tagprefix="wiki-", $cli_args="", $url="wiki?name=", $long=0) {
    foreach (db("SELECT tagname AS name FROM tag WHERE tagname LIKE '$tagprefix%';") as $page) {
        $page = substr($page["name"], strpos($page["name"], "-") + 1);
        print "<li>$page\n";
        $q = "escapeshellarg";
        $html = shell_exec("fossil --nocgi wiki export $cli_args --html {$q($page)} -R {$q($_SERVER['FOSSIL_REPOSITORY'])} 2>&1");
        insert_meta(
            $url . $page,
            html_meta($page, $html, $long)
        );
    }
}
#-- technotes
function wiki_event() {
    wiki_pages("event-", "--technote", "technote/", 1);
}

#-- scan *.md/wiki files
function doc_pages() {
    foreach (db("SELECT name FROM filename") as $page) {
        $fn = $page["name"];
        if (!preg_match("/\.(md|wiki)$/", $fn)) {
            continue;
        }
        print "<li>$fn\n";
        $q = "escapeshellarg";
        $md = shell_exec("fossil --nocgi cat {$q($fn)} -R {$q($_SERVER['FOSSIL_REPOSITORY'])} 2>&1");
        if (!$md) {
            continue;
        }
        $meta = html_meta($fn, $md);
        insert_meta("doc/trunk/$fn", $meta);
        insert_meta("doc/tip/$fn", $meta);
    }
}

# <meta> and <link>s for a wiki page
#  ยท wiki?name=PageName
function html_meta($name, $html, $long=0) {

    # cleanup
    $html = preg_replace("~<table.+?</table>~s", "", $html);
    $text = trim(preg_replace("~\s+~", " ", strip_tags($html)));
    $desc = substr($text, 0, 250);
    
    # prepare tags
    $twitter = trim(get_config("project-twitter", PROJECT_TWITTER), "@");
    $h = "h";
    if ($long && preg_match("~<h\d>(.+)</h\d>~", $html, $uu)) {
        $name = $uu[1];  // technote pages require a headline
    }
    
    # check for image
    if (preg_match("~<img[^>]+ src=[\"']? ([^\"'\s>]+)~x", $html, $uu) || preg_match("~(raw/\w+) \?m=image/~x", $html, $uu) or $uu=["","logo"]) {
        $img = $uu[1];
        if (strstr($img, "://")) {
        }
        elseif (preg_match("~raw/|doc/|^logo$~", $img)) {
            $img = $_SERVER["FOSSIL_SELF"] . $img;
        }
        elseif ($img[0] == "/") {
            $img = "https://$_SERVER[SERVER_NAME]$img";
        }
        $summary = $long ? "summary_large_image" : "summary";
        $meta = <<<EOF
  <meta name="twitter:card" content="$summary">
  <meta name="twitter:site" content="@$twitter">
  <meta name="twitter:creator" content="@$twitter">
  <meta name="twitter:title" content="{$h($name)}">
  <meta name="twitter:description" content="{$h($desc)}">
  <meta name="twitter:image" content="{$h($img)}">
  <meta name="twitter:image:src" content="{$h($img)}">
EOF;
        # could add FB (og:image, og:title, og:description, og:url) as well
    }
    else {
        $meta = "  <meta name=description content=\"{$h($desc)}\">\n";
    }

    $meta = preg_replace("~(?<!:)//+~", "/", $meta); // replace any double // in paths
    return $meta;
}