123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140(*
* Copyright (c) 2010-2013 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2013 Richard Mortier <mort@cantab.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*)(** Blog management: entries, ATOM feeds, etc.
An Atom feed has metadata plus a way to retrieve entries. *)openPrintfopenLwt.InfixopenCowopenAtom_feed(** A feed is made up of Entries. *)moduleEntry=struct(** An entry in a feed: metadata plus a filename [body]. *)typet={updated:Date.date;authors:Atom.authorlist;subject:string;permalink:string;body:string;}(** [permalink feed entry] returns the permalink URI for [entry] in [feed]. *)letpermalinkfeedentry=sprintf"%s%s%s"feed.base_urifeed.identry.permalink(** Compare two entries. *)letcompareab=compare(Date.atom_dateb.updated)(Date.atom_datea.updated)(** [to_html feed entry] converts a blog entry in the given feed into an
Html.t fragment. *)letto_html~feed~entry=feed.read_entryentry.body>|=funcontent->letauthors=List.map(fun{Atom.name;uri;_}->letauthor_uri=matchuriwith|None->Uri.of_string""(* TODO *)|Someuri->Uri.of_stringuriinname,author_uri)entry.authorsinletdate=Date.html_of_dateentry.updatedinlettitle=letpermalink=Uri.of_string(permalinkfeedentry)inentry.subject,permalinkinFoundation.Blog.post~title~date~authors~content(** [to_atom feed entry] *)letto_atomfeedentry=letlinks=[Atom.mk_link~rel:`alternate~typ:"text/html"(Uri.of_string(permalinkfeedentry))]inletmeta={Atom.id=permalinkfeedentry;title=entry.subject;subtitle=None;author=(matchentry.authorswith|[]->None|author::_->Someauthor);updated=Date.atom_dateentry.updated;rights=None;links;}infeed.read_entryentry.body>|=funcontent->{Atom.entry=meta;summary=None;base=None;content}end(** Entries separated by <hr /> tags *)letdefault_separator=Html.(hrempty)(** [to_html ?sep feed entries] renders a series of entries in a feed, separated
by [sep], defaulting to [default_separator]. *)letto_html?(sep=default_separator)~feed~entries=letrecconcat=function|[]->Lwt.returnHtml.empty|hd::tl->Entry.to_html~feed~entry:hd>>=funhd->concattl>|=funtl->Html.list[hd;sep;tl]inconcat(List.sortEntry.compareentries)(** [to_atom feed entries] generates a time-ordered ATOM RSS [feed] for a
sequence of [entries]. *)letto_atom~feed~entries=let{title;subtitle;base_uri;id;rights;_}=feedinletid=base_uri^idinletmk_urix=Uri.of_string(id^x)inletentries=List.sortEntry.compareentriesinletupdated=Date.atom_date(List.hdentries).Entry.updatedinletlinks=[Atom.mk_link(mk_uri"atom.xml");Atom.mk_link~rel:`alternate~typ:"text/html"(mk_uri"")]inletatom_feed={Atom.id;title;subtitle;author=feed.author;rights;updated;links}inLwt_list.map_s(Entry.to_atomfeed)entries>|=funentries->{Atom.feed=atom_feed;entries}(** [recent_posts feed entries] . *)letrecent_posts?(active="")feedentries=letentries=List.sortEntry.compareentriesinList.map(fune->letlink=Entry.(e.subject,Uri.of_string(Entry.permalinkfeede))inife.Entry.subject=activethen`active_linklinkelse`linklink)entries