From: rich Date: Sun, 10 Oct 2004 14:44:50 +0000 (+0000) Subject: Factored out the 'what links here' code into cocanwiki_links library. X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;ds=sidebyside;h=f249bda689881753ba729e48cce6ddf84ffeb3c2;p=cocanwiki.git Factored out the 'what links here' code into cocanwiki_links library. Fixed it so that it can discover links mediated by redirects. max_redirect moved from page.ml because it's used in other places. --- diff --git a/scripts/cocanwiki.ml b/scripts/cocanwiki.ml index 5664582..8cca6fb 100644 --- a/scripts/cocanwiki.ml +++ b/scripts/cocanwiki.ml @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: cocanwiki.ml,v 1.15 2004/10/07 16:54:24 rich Exp $ + * $Id: cocanwiki.ml,v 1.16 2004/10/10 14:44:50 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 @@ -222,3 +222,6 @@ let linkname_of_sectionname str = (* List of extensions currently registered. *) type extension_t = Dbi.connection -> int -> string -> string let extensions = ref ([] : (string * extension_t) list) + +(* Maximum degree of redirection. *) +let max_redirect = 4 diff --git a/scripts/cocanwiki_links.ml b/scripts/cocanwiki_links.ml index 101ca64..99ee987 100644 --- a/scripts/cocanwiki_links.ml +++ b/scripts/cocanwiki_links.ml @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: cocanwiki_links.ml,v 1.3 2004/10/07 12:22:11 rich Exp $ + * $Id: cocanwiki_links.ml,v 1.4 2004/10/10 14:44:50 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 @@ -22,6 +22,8 @@ open ExtString open ExtList +open Cocanwiki + let split_tags_re = Pcre.regexp ~flags:[`DOTALL] "<.*?>|[^<]+" let internal_re = Pcre.regexp "class=\"internal\"" let newpage_re = Pcre.regexp "class=\"newpage\"" @@ -122,3 +124,50 @@ let update_links_for_page dbh hostid page = let links = get_links_from_section dbh hostid content in List.iter (insert_link dbh hostid page) links | _ -> assert false) + +(* Because of redirects, getting the list of pages which link to this + * page isn't a matter of just doing 'select from_url from links ...'. + * We also look at pages which redirect to this URL (for redirections + * of degrees 1 through 4 = max_redirect). + *) +let what_links_here (dbh : Dbi.connection) hostid page = + (* Build up the complete list of URLs which redirect to the target + * page, within max_redirect redirections. This is sort of like + * Prim's algorithm. + *) + let urls = ref [page] in + let found = ref true in + let i = ref 1 in + while !found && !i <= max_redirect do + let qs = Dbi.placeholders (List.length !urls) in + let sql = + "select url from pages + where hostid = ? + and url is not null and redirect is not null + and url not in " ^ qs ^ " and redirect in " ^ qs in + let sth = dbh#prepare_cached sql in + let args = List.map (fun s -> `String s) !urls in + sth#execute (`Int hostid :: (args @ args)); + let new_urls = sth#map (function [`String s] -> s | _ -> assert false) in + urls := !urls @ new_urls; + found := new_urls <> []; + incr i + done; + + let urls = !urls in + + (* Now find any pages which link to one of these target pages. For + * convenience we also select out the titles. + *) + let qs = Dbi.placeholders (List.length urls) in + let sth = + dbh#prepare_cached + ("select li.from_url, p.title + from links li, pages p + where li.hostid = ? and li.to_url in " ^ qs ^ " + and li.hostid = p.hostid and li.from_url = p.url") in + sth#execute (`Int hostid :: (List.map (fun s -> `String s) urls)); + + sth#map (function + | [`String url; `String title] -> url, title + | _ -> assert false) diff --git a/scripts/cocanwiki_links.mli b/scripts/cocanwiki_links.mli index b55e26c..de2b615 100644 --- a/scripts/cocanwiki_links.mli +++ b/scripts/cocanwiki_links.mli @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: cocanwiki_links.mli,v 1.2 2004/09/28 11:28:39 rich Exp $ + * $Id: cocanwiki_links.mli,v 1.3 2004/10/10 14:44:50 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 @@ -22,3 +22,5 @@ val get_links_from_section : Dbi.connection -> int -> string -> string list val update_links_for_page : Dbi.connection -> int -> string -> unit val insert_link : Dbi.connection -> int -> string -> string -> unit + +val what_links_here : Dbi.connection -> int -> string -> (string * string) list diff --git a/scripts/page.ml b/scripts/page.ml index 7e2f02d..29dd3bb 100644 --- a/scripts/page.ml +++ b/scripts/page.ml @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: page.ml,v 1.26 2004/10/07 16:54:24 rich Exp $ + * $Id: page.ml,v 1.27 2004/10/10 14:44:50 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 @@ -32,9 +32,6 @@ open Cocanwiki_ok open Cocanwiki_date open Cocanwiki_server_settings -(* Maximum level of redirection. *) -let max_redirect = 4 - type fp_status = FPOK of int * string * string * Dbi.datetime * bool | FPRedirect of string | FPNotFound diff --git a/scripts/what_links_here.ml b/scripts/what_links_here.ml index f05994c..80a7c4f 100644 --- a/scripts/what_links_here.ml +++ b/scripts/what_links_here.ml @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: what_links_here.ml,v 1.3 2004/10/04 15:19:56 rich Exp $ + * $Id: what_links_here.ml,v 1.4 2004/10/10 14:44:50 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 @@ -26,6 +26,7 @@ open Printf open Cocanwiki open Cocanwiki_template +open Cocanwiki_links let run r (q : cgi) (dbh : Dbi.connection) hostid _ _ = let template = get_template dbh hostid "what_links_here.html" in @@ -40,18 +41,11 @@ let run r (q : cgi) (dbh : Dbi.connection) hostid _ _ = let title = sth#fetch1string () in template#set "title" title; - let sth = - dbh#prepare_cached "select l.from_url, p.title from links l, pages p - where l.hostid = ? and l.to_url = ? - and l.hostid = p.hostid and l.from_url = p.url" in - sth#execute [`Int hostid; `String page]; - + let pages = what_links_here dbh hostid page in let table = - sth#map - (function [`String page; `String title] -> - [ "page", Template.VarString page; - "title", Template.VarString title ] - | _ -> assert false) in + List.map (fun (page, title) -> + [ "page", Template.VarString page; + "title", Template.VarString title ]) pages in template#table "pages" table; template#conditional "pages_empty" (table = []);