#!/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;
}