Index: openacs-4/packages/xowiki/tcl/syndicate-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/syndicate-procs.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowiki/tcl/syndicate-procs.tcl 1 Aug 2007 21:39:24 -0000 1.19.2.2
@@ -0,0 +1,375 @@
+namespace eval ::xowiki {
+ #
+ # RSS 2.0 support
+ #
+ Class XMLSyndication -parameter {package_id}
+
+ XMLSyndication instproc init {} {
+ my set xmlMap [list & "&" < "<" > ">" \" """ ' "'"]
+ }
+
+ XMLSyndication instproc tag {{-atts } name value} {
+ my instvar xmlMap
+ set attsXML ""
+ if {[info exists atts]} {
+ foreach {attName attValue} $atts {
+ append attsXML " $attName='[string map [list ' {'} { } { }] $attValue]'"
+ }
+ }
+ return <$name$attsXML>[string map $xmlMap $value]$name>
+ }
+
+ Class RSS -superclass XMLSyndication -parameter {
+ maxentries
+ {name_filter ""}
+ {entries_of ""}
+ {days ""}
+ {css ""}
+ {siteurl "[ad_url]"}
+ {description ""}
+ {language en-us}
+ {title ""}
+ } \
+ -ad_doc {
+ Report content of xowiki folder in rss 2.0 format. The
+ reporting order is descending by date. The title of the feed
+ is taken from the title, the description
+ is taken from the description field of the folder object.
+
+ @param maxentries maximum number of entries retrieved
+ @param days report entries changed in speficied last days
+ @param name_filter include only pages matching the provided regular expression (postgres)
+ }
+
+ RSS instproc css_link {} {
+ my instvar css
+ if {$css ne ""} {
+ #
+ # firefox 2.0 appears to overwrite the style info, so one has to use such ugly tricks:
+ # http://www.blingblog.info/2006/10/30/firefox-big-browser/
+ # when we want to use custom style sheets
+ #
+ set user_agent [string tolower [ns_set get [ns_conn headers] User-Agent]]
+ set filler [expr {[string first firefox $user_agent] >- 1 ?
+ "" : ""
+ }]
+ set css_link [expr {[string match /* $css] ? $css : "/resources/xowiki/$css"}]
+ return "\n\n$filler"
+ }
+ return ""
+ }
+
+ RSS instproc head {} {
+ my instvar title link description language
+ return "[my css_link]
+
+
+ [my tag title $title]
+ [my tag link $link]
+ [my tag description $description]
+ [my tag language $language]
+ [my tag generator xowiki]"
+ }
+
+ RSS instproc item {-creator -title -link -guid -description -pubdate } {
+ append result - \n\
+ [my tag dc:creator $creator ] \n\
+ [my tag title $title ] \n\
+ [my tag link $link ] \n\
+ [my tag -atts {isPermaLink false} guid $guid] \n\
+ [my tag description $description ] \n\
+ [my tag pubDate $pubdate ] \n\
+
\n
+ }
+
+ RSS instproc tail {} {
+ return "\n\n\n"
+ }
+
+
+ RSS instproc limit {} {
+ my instvar maxentries
+ if {[info exists maxentries] && $maxentries ne ""} {
+ return $maxentries
+ }
+ return ""
+ }
+
+ RSS instproc extra_where_clause {} {
+ my instvar name_filter days entries_of package_id
+ set extra_where_clause ""
+ if {$name_filter ne ""} {
+ append extra_where_clause " and ci.name ~ E'$name_filter' "
+ }
+ if {$days ne ""} {
+ append extra_where_clause "and " \
+ [::xo::db::sql since_interval_condition p.last_modified "$days days"]
+ }
+ if {$entries_of ne ""} {
+ set form_items [list]
+ set folder_id [$package_id folder_id]
+ foreach t [split $entries_of |] {
+ set form_item_id [::xowiki::Form lookup -name $t -parent_id $folder_id]
+ if {$form_item_id == 0} {error "Cannot lookup page $t"}
+ lappend form_items $form_item_id
+ }
+ append extra_where_clause " and p.page_template in ('[join $form_items ',']') and p.page_instance_id = p.revision_id "
+
+ my set base_table xowiki_form_pagex
+ }
+ return $extra_where_clause
+ }
+
+ RSS instproc render {} {
+ my instvar package_id max_entries name_filter title days description siteurl base_table
+ set folder_id [::$package_id folder_id]
+
+ if {$description eq ""} {set description [::$folder_id set description]}
+ my set link $siteurl[site_node::get_url_from_object_id -object_id $package_id]
+
+ set base_table xowiki_pagex
+ set extra_where_clause [my extra_where_clause]
+
+ if {$base_table ne "xowiki_pagex"} {
+ # we assume, we retrieve the entries for a form
+ set extra_from ""
+ } else {
+ # return always instance_attributes
+ set extra_from "left join \
+ xowiki_page_instance on (p.revision_id = page_instance_id)"
+ }
+
+ set sql [::xo::db::sql select \
+ -vars "s.body, p.name, p.creator, p.title, p.page_id, instance_attributes, \
+ p.object_type as content_type, p.last_modified, p.description" \
+ -from "syndication s, cr_items ci, $base_table p $extra_from" \
+ -where "ci.parent_id = $folder_id and ci.live_revision = s.object_id \
+ and ci.publish_status <> 'production' \
+ $extra_where_clause \
+ and s.object_id = p.page_id" \
+ -orderby "p.last_modified desc" \
+ -limit [my limit]]
+
+ set content [my head]
+ db_foreach get_pages $sql {
+ if {[string match "::*" $name]} continue
+ if {$content_type eq "::xowiki::PageTemplate"} continue
+
+ set description [string trim $description]
+ if {$description eq ""} {set description $body}
+ if {$title eq ""} {set title $name}
+ set time [::xo::db::tcl_date $last_modified tz]
+ set link [::xowiki::Portlet detail_link \
+ -package_id $package_id -name $name \
+ -absolute true \
+ -instance_attributes $instance_attributes]
+
+ #append title " ($content_type)"
+ set time "[clock format [clock scan $time] -format {%a, %d %b %Y %T}] ${tz}00"
+ append content [my item \
+ -creator $creator \
+ -title $title \
+ -link $link \
+ -guid $siteurl/$page_id \
+ -description $description \
+ -pubdate $time \
+ ]
+ }
+
+ append content [my tail]
+ return $content
+ }
+
+ Class Podcast -superclass RSS -parameter {
+ {subtitle ""}
+ {description ""}
+ {summary ""}
+ {author ""}
+ {explicit "no"}
+ }
+
+
+ Podcast instproc head {} {
+ my instvar title link description language subtitle summary author explicit
+
+ return "[my css_link]
+
+
+ [my tag title $title]
+ [my tag link $link]
+ [my tag description $description]
+ [my tag language $language]
+ [my tag generator xowiki]
+ [my tag itunes:subtitle $subtitle]
+ [my tag itunes:summary $summary]
+ [my tag itunes:author $author]
+ [my tag itunes:explicit $explicit]
+"
+ }
+
+ Podcast instproc item {
+ -author -title -subtitle -description
+ -link -guid -pubdate
+ -mime_type -duration -keywords} {
+ append result \n - \
+ [my tag title $title] \n\
+ [my tag link $link ] \n\
+ [my tag -atts {isPermaLink true} guid $guid] \n\
+ [my tag pubDate $pubdate] \n\
+ [my tag itunes:duration $duration] \n\
+ [my tag author $author ] \n\
+ [my tag description $description ] \n\
+ [my tag itunes:subtitle $subtitle ] \n\
+ [my tag itunes:author $author ] \n\
+ [my tag itunes:keywords $keywords ] \n\
+ " " \
+ \n
\n
+ }
+
+
+ Podcast instproc render {} {
+ my instvar package_id max_entries name_filter title days \
+ summary subtitle description author siteurl
+
+ set folder_id [::$package_id folder_id]
+ if {$description eq ""} {set description [::$folder_id set description]}
+ if {$summary eq ""} {set summary $description}
+ if {$subtitle eq ""} {set subtitle $title}
+
+ my set link $siteurl[site_node::get_url_from_object_id -object_id $package_id]
+
+ set content [my head]
+ set sql [::xo::db::sql select \
+ -vars * \
+ -from "xowiki_podcast_itemi p, cr_items ci, cr_mime_types m" \
+ -where "ci.parent_id = $folder_id and ci.item_id = p.item_id \
+ and ci.live_revision = p.object_id \
+ and p.mime_type = m.mime_type \
+ and ci.publish_status <> 'production' [my extra_where_clause]" \
+ -orderby "p.pub_date asc" \
+ -limit [my limit]]
+
+ db_foreach get_pages $sql {
+ if {$content_type ne "::xowiki::PodcastItem"} continue
+ if {$title eq ""} {set title $name}
+ set link [::$package_id pretty_link -download true -absolute true -siteurl $siteurl $name]
+ append content [my item \
+ -author $creator -title $title -subtitle $subtitle \
+ -description $description \
+ -link $link -mime_type $mime_type \
+ -guid $link -pubdate $pub_date -duration $duration \
+ -keywords $keywords]
+ }
+
+ append content [my tail]
+ return $content
+ }
+
+ Class Timeline -superclass XMLSyndication \
+ -parameter {user_id {limit 1000}}
+
+ Timeline instproc reverse list {
+ set result [list]
+ for {set i [expr {[llength $list] - 1}]} {$i >= 0} {incr i -1} {
+ lappend result [lindex $list $i]
+ }
+ return $result
+ }
+
+ Timeline instproc render {} {
+ my instvar package_id
+ set folder_id [::$package_id folder_id]
+ set where_clause ""
+ set limit ""
+
+ set last_user ""
+ set last_item ""
+ set last_clock ""
+ if {[my exists user_id]} { append where_clause " and o.creation_user = [my user_id] " }
+ if {[my exists limit]} { set limit [my limit] }
+
+ ::xo::OrderedComposite items -destroy_on_cleanup
+ set sql [::xo::db::sql select \
+ -vars "ci.name, o.creation_user, cr.publish_date, o2.creation_date, \
+ cr.item_id, ci.parent_id, cr.title" \
+ -from "cr_items ci, cr_revisions cr, acs_objects o, acs_objects o2" \
+ -where "cr.item_id = ci.item_id and o.object_id = cr.revision_id
+ and o2.object_id = cr.item_id
+ and ci.parent_id = :folder_id and o.creation_user is not null
+ $where_clause" \
+ -orderby "revision_id desc" \
+ -limit $limit]
+ db_foreach get_pages $sql {
+ set publish_date [::xo::db::tcl_date $publish_date tz]
+ set creation_date [::xo::db::tcl_date $creation_date tz]
+ set clock [clock scan $publish_date]
+
+ if {$last_user == $creation_user && $last_item == $item_id && $last_clock ne ""} {
+ #my log "--clockdiff = [expr {$last_clock - $clock }] $name [clock format $clock -format {%b %d %Y %X %Z} -gmt true]"
+ if {($last_clock - $clock) < 7500 } {
+ #my log "--clock ignore change due to cockdiff"
+ continue
+ }
+ }
+ set o [Object new]
+ foreach att {item_id creation_user item_id clock name publish_date parent_id title} {
+ $o set $att [set $att]
+ }
+ $o set operation [expr {$creation_date eq $publish_date ? "created" : "modified"}]
+
+ items add $o
+ foreach {last_user last_item last_clock} [list $creation_user $item_id $clock] break
+ }
+
+ # The following loop tries to distinguis between create and modify by age.
+ # This does not work in cases, where we get just a limited amount
+ # or restricted entries
+# if {$limit eq ""} {
+# foreach i [my reverse [items children]] {
+# set key seen([$i set item_id])
+# if {[info exists $key]} {
+# $i set operation modified
+# } else {
+# $i set operation created
+# set $key 1
+# }
+# }
+# }
+
+ foreach i [items children] {
+ set key contrib([clock format [$i set clock] -format "%Y-%m-%d" -gmt true],[$i set creation_user],[$i set item_id])
+ lappend $key $i
+ }
+
+ set result \n
+
+ foreach c [lsort -decreasing [array names contrib]] {
+ if {[llength $contrib($c)] == 1} {
+ set i $contrib($c)
+ set title [$i set title]
+ set user [::xo::get_user_name [$i set creation_user]]
+ set event "$user [$i set operation] [$i set title] [$i set name]"
+ } else {
+ set i [lindex $contrib($c) 0]
+ set event "Contributions by [::xo::get_user_name [$i set creation_user]] on [clock format [$i set clock] -format {%b %d %Y} -gmt true]\n"
+ set title "[$i set title] ([llength $contrib($c)])"
+ foreach j $contrib($c) {
+ set stamp [clock format [$j set clock] -format "%X %Z" -gmt true]
+ append event "- $stamp: [$j set operation]
" \n
+ }
+ append event "
" \n
+ }
+ set stamp [clock format [$i set clock] -format "%b %d %Y %X %Z" -gmt true]
+ set user [::xo::get_user_name [$i set creation_user]]
+ append result [my tag -atts [list \
+ start $stamp \
+ title $title \
+ link [$package_id pretty_link [$i set name]]] \
+ event $event] \n
+ }
+ append result \n
+ return $result
+ }
+}