(* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. * $Id: links.ml,v 1.2 2004/11/02 18:47:54 rich Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *) open Apache open Registry open Cgi open Printf open Cocanwiki open Cocanwiki_template open Cocanwiki_links (* This script produces the links database for the whole site (if * called without the 'page' parameter), or else just for a particular * page. If called with 'page' and 'type' parameters together, then it * can show inbound or outbound links only. The format in all cases is a * simple machine-parsable text file. *) let run r (q : cgi) (dbh : Dbi.connection) hostid _ _ = let template = get_template dbh hostid "links.txt" in if q#param_exists "page" then ( let page = q#param "page" in let page = if page = "" then "index" else page in if q#param_exists "type" then ( let type_ = q#param "type" in if type_ = "inbound" then ( (* This is "what links here". We're interested in indirect * links too, so use Cocanwiki_links.what_links_here function. *) let links = what_links_here dbh hostid page in let links = List.map fst links in q#header ~content_type:"text/plain" (); List.iter (fun url -> ignore (print_endline r url)) links ) else if type_ = "outbound" then ( (* Display a list of links outbound from this page. *) let sth = dbh#prepare_cached "select to_url from links where hostid = ? and from_url = ?" in sth#execute [`Int hostid; `String page]; q#header ~content_type:"text/plain" (); sth#iter (function [`String url] -> ignore (print_endline r url) | _ -> assert false) ) else failwith "'type' parameter should be 'inbound' or 'outbound'" ) else ( (* Just return the single-row "links database" relating to this * page. *) let sth = dbh#prepare_cached "select to_url from links where hostid = ? and from_url = ?" in sth#execute [`Int hostid; `String page]; let table = sth#map (function [`String to_url] -> [ "to", Template.VarString to_url ] | _ -> assert false) in let table = [ [ "from", Template.VarString page; "to", Template.VarTable table ] ] in template#table "links" table; q#template ~content_type:"text/plain" template ) ) else ( (* Links database for whole site in the simple format required by * the TouchGraph application. We don't know anything about external * links, so we don't include them. However we do include links to * non-existant internal pages. *) let h = Hashtbl.create 1024 in let add_link from_url to_url = let xs = try Hashtbl.find h from_url with Not_found -> [] in let xs = to_url :: xs in Hashtbl.replace h from_url xs in let sth = dbh#prepare_cached "select from_url, to_url from links where hostid = ?" in sth#execute [`Int hostid]; sth#iter (function [`String from_url; `String to_url] -> add_link from_url to_url | _ -> assert false); (* Don't forget redirects! They're kinda like links ... *) let sth = dbh#prepare_cached "select url, redirect from pages where hostid = ? and url is not null and redirect is not null" in sth#execute [`Int hostid]; sth#iter (function [`String url; `String redirect] -> add_link url redirect | _ -> assert false); let keys h = Hashtbl.fold (fun key _ xs -> key :: xs) h [] in let table = List.map (fun from -> let xs = Hashtbl.find h from in let table = List.map (fun to_ -> [ "to", Template.VarString to_ ]) xs in [ "from", Template.VarString from; "to", Template.VarTable table ] ) (keys h) in template#table "links" table; q#template ~content_type:"text/plain" template ) let () = register_script ~restrict:[CanView] run