1 (* COCANWIKI - a wiki written in Objective CAML.
2 * Written by Richard W.M. Jones <rich@merjis.com>.
3 * Copyright (C) 2004 Merjis Ltd.
4 * $Id: links.ml,v 1.6 2006/12/06 09:46:57 rich Exp $
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 open Cocanwiki_template
31 (* This script produces the links database for the whole site (if
32 * called without the 'page' parameter), or else just for a particular
33 * page. If called with 'page' and 'type' parameters together, then it
34 * can show inbound or outbound links only. The format in all cases is a
35 * simple machine-parsable text file.
37 let run r (q : cgi) dbh hostid _ _ =
38 let template = get_template r dbh hostid "links.txt" in
40 if q#param_exists "page" then (
41 let page = q#param "page" in
42 let page = if page = "" then "index" else page in
44 if q#param_exists "type" then (
45 let type_ = q#param "type" in
47 if type_ = "inbound" then (
48 (* This is "what links here". We're interested in indirect
49 * links too, so use Cocanwiki_links.what_links_here function.
51 let links = what_links_here dbh hostid page in
52 let links = List.map fst links in
54 q#header ~content_type:"text/plain" ();
56 List.iter (fun url -> ignore (print_endline r url)) links
58 ) else if type_ = "outbound" then (
59 (* Display a list of links outbound from this page. *)
62 "select to_url from links
63 where hostid = $hostid and from_url = $page" in
65 q#header ~content_type:"text/plain" ();
67 List.iter (fun url -> ignore (print_endline r url)) rows
70 failwith "'type' parameter should be 'inbound' or 'outbound'"
73 (* Just return the single-row "links database" relating to this
77 "select to_url from links
78 where hostid = $hostid and from_url = $page" in
81 List.map (fun to_url ->
82 [ "to", Template.VarString to_url ]) rows in
84 [ [ "from", Template.VarString page;
85 "to", Template.VarTable table ] ] in
86 template#table "links" table;
88 q#template ~content_type:"text/plain" template
91 (* Links database for whole site in the simple format required by
92 * the TouchGraph application. We don't know anything about external
93 * links, so we don't include them. However we do include links to
94 * non-existant internal pages.
96 let h = Hashtbl.create 1024 in
97 let add_link from_url to_url =
98 let xs = try Hashtbl.find h from_url with Not_found -> [] in
99 let xs = to_url :: xs in
100 Hashtbl.replace h from_url xs
103 let rows = PGSQL(dbh) "select from_url, to_url from links
104 where hostid = $hostid" in
106 List.iter (fun (from_url, to_url) ->
107 add_link from_url to_url) rows;
109 (* Don't forget redirects! They're kinda like links ... *)
110 let rows = PGSQL(dbh) "select url, redirect from pages
111 where hostid = $hostid and url is not null
112 and redirect is not null" in
115 | (Some url, Some redirect) -> add_link url redirect
119 let keys h = Hashtbl.fold (fun key _ xs -> key :: xs) h [] in
124 let xs = Hashtbl.find h from in
126 List.map (fun to_ -> [ "to", Template.VarString to_ ]) xs in
127 [ "from", Template.VarString from;
128 "to", Template.VarTable table ]
130 template#table "links" table;
132 q#template ~content_type:"text/plain" template
136 register_script ~restrict:[CanView] run