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] + } + + 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 + } +}