Index: openacs-4/packages/rss-support/rss-support.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/rss-support/rss-support.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/rss-support/rss-support.info 4 Nov 2001 23:17:40 -0000 1.1 @@ -0,0 +1,45 @@ + + + + + RSS Support + RSS Support + f + t + + + + oracle + postgresql + + Andrew Grumet + Jerry Asher + Dave Bauer + Basic support for RSS generation (and parsing). RDF Site Summary (RSS) is a lightweight multipurpose extensible metadata description and syndication format. This package can be used to publish ACS objects in a manner useful to other websites and webservices. + + For each item (news event, ticket, bboard message, ...) that you want to publish, you create a property list that describes that item (url to item, title of item, description of item, etc.). You pass a list of those items +(and some other parameters) to rss_gen, and it will generate your XML for you. + +<ul> +<li> <a href='http://www.google.com/search?q=rss+0.91'>RSS 0.91 specification</a> +<li> <a href='http://groups.yahoo.com/group/rss-dev/files/specification.html'>RSS 1.0 specification</a> +</ul> + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/rss-support/sql/postgresql/rss-generation-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/rss-support/sql/postgresql/rss-generation-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/rss-support/sql/postgresql/rss-generation-create.sql 4 Nov 2001 23:17:40 -0000 1.1 @@ -0,0 +1,32 @@ +create table rss_generation_subscriptions ( + subscription_id integer, + impl_name varachar(100), + context_identifier varchar(100), + timeout integer +); + +comment on table rss_generation_subscriptions is ' + Table for storing the different parts of the site we will generate + summaries for. +'; + +comment on column rss_generation_subscriptions.subscription_id is ' + Subscriptions are ACS objects. They will typically inherit + permission from a package instance. +'; + +comment on column rss_generation_subscriptions.impl_name is ' + The implementation which will provide summary information and + update status. +'; + +comment on column rss_generation_subscriptions.context_identifier is ' + An identifier unique to the site section whose content is to be + summarized. A context identifier need not be a package instance + id. We will suggest a convention but the format is entirely up to + the implementors. +'; + +comment on column rss_generation_subscriptions.timeout is ' + The minimum number of seconds between summary builds. +'; Index: openacs-4/packages/rss-support/sql/postgresql/rss-generation-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/rss-support/sql/postgresql/rss-generation-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/rss-support/sql/postgresql/rss-generation-sc-create.sql 4 Nov 2001 23:17:40 -0000 1.1 @@ -0,0 +1,48 @@ +-- +-- ACS-SC Contract: RssGenerationSubscriber +-- + +select acs_sc_contract__new ( + 'RssGenerationSubscriber', -- contract_name + 'RSS Generation Subscriber' -- contract_desc +); + +select acs_sc_msg_type__new ( + 'RssGenerationSubscriber.Datasource.InputType', + 'context_identifier:string' +); + +select acs_sg_msg_type__new ( + 'RssGenerationSubscriber.Datasource.OutputType', + 'datasource:string' -- ???? +); + +select acs_sc_operation__new ( + 'RssGenerationSubscriber', -- contract_name + 'datasource', -- operation_name + 'Data Source', -- operation_desc + 'f', -- operation_iscachable_p, + 1, -- operation_nargs + 'RssGenerationSubscriber.Datasource.InputType', -- operation_inputtype + 'RssGenerationSubscriber.Datasource.OutputType' -- operation_outputtype +); + +select acs_sc_msg_type__new ( + 'RssGenerationSubscriber.LastUpdated.InputType', + 'context_identifier:string' +); + +select acs_sg_msg_type__new ( + 'RssGenerationSubscriber.LastUpdated.OutputType', + 'lastupdate:timestamp' +); + +select acs_sc_operation__new ( + 'RssGenerationSubscriber', -- contract_name + 'lastUpdated', -- operation_name + 'Last Updated', -- operation_desc + 'f', -- operation_iscachable_p, + 1, -- operation_nargs + 'RssGenerationSubscriber.LastUpdated.InputType', -- operation_inputtype + 'RssGenerationSubscriber.LastUpdated.OutputType' -- operation_outputtype +); Index: openacs-4/packages/rss-support/sql/postgresql/rss-support-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/rss-support/sql/postgresql/rss-support-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/rss-support/sql/postgresql/rss-support-create.sql 4 Nov 2001 23:17:40 -0000 1.1 @@ -0,0 +1,2 @@ +\i rss-generation-create.sql +\i rss-generation-sc-create.sql Index: openacs-4/packages/rss-support/tcl/rss-generation-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/rss-support/tcl/rss-generation-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/rss-support/tcl/rss-generation-procs.tcl 4 Nov 2001 23:17:40 -0000 1.1 @@ -0,0 +1,637 @@ +# /tcl/rss-defs.tcl +ad_library { + procs to generate rss feeds + procs to help with rssness + @author jerry@theashergroup.com [jerry@theashergroup.com] + @creation-date Fri Oct 26 11:43:26 2001 + @cvs-id +} + + +### +# rss +# generates an rss feed given channel information +# and item information +### + +#Convert to ad_register_proc if we plan to keep. +#ns_register_proc GET /*.rss ns_sourceproc +#ns_register_proc POST /*.rss ns_sourceproc +#ns_register_proc HEAD /*.rss ns_sourceproc +#ns_register_proc PUT /*.rss ns_putscript + +ad_proc rss_gen_100 { + { + -channel_title "" + -channel_link "" + -channel_description "" + -image "" + -items "" + -channel_copyright "" + -channel_managingEditor "" + -channel_webMaster "" + -channel_pubDate "" + } +} { + generate an rss 1.0 xml feed + very basic rss 1.0, with no modules implemented.... +} { + + set rss "" + + if {[empty_string_p $channel_title]} { + error "argument channel_title not provided" + } + if {[empty_string_p $channel_link]} { + error "argument channel_link not provided" + } + if {[empty_string_p $channel_description]} { + error "argument channel_description not provided" + } + + set channel_date [clock format [clock seconds] -format "%Y-%m-%dT%H:%M"] + + append rss "" + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_title] + append rss "\n" + + append rss "" + append rss $channel_link + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_description] + append rss "\n" + + if {[empty_string_p $channel_pubDate]} { + append rss "$channel_date\n" + } else { + append rss "[ad_quotehtml $channel_pubDate]\n" + } + + if {![empty_string_p $channel_copyright]} { + append rss "" + append rss [ad_quotehtml $channel_copyright] + append rss "\n" + } + + if {![empty_string_p $channel_managingEditor]} { + append rss "" + append rss [ad_quotehtml $channel_managingEditor] + append rss "\n" + } + + if {![empty_string_p $channel_webMaster]} { + append rss "" + append rss [ad_quotehtml $channel_webMaster] + append rss "\n" + } + + + if {[empty_string_p $image]} { + set logo_rss "/graphics/openacs_logo_rss.gif" + set url [ad_parameter systemurl ""] + append url $logo_rss + set title $channel_title + set link $channel_link + set size [ns_gifsize [ns_url2file $logo_rss]] + set image [list \ + url $url \ + title $title \ + link $link \ + width [lindex $size 0] \ + height [lindex $size 1]] + } + + array set imarray $image + + # channel image handling + append rss "\n" + + append rss "\n" + append rss "\n" + + # channel item handling + foreach item $items { + array unset iarray + array set iarray $item + append rss "\n" + } + + append rss "\n" + append rss "\n" + append rss "\n" + + # now top level image + append rss "\n" + append rss "[ad_quotehtml $imarray(title)]\n" + append rss "$imarray(url)\n" + append rss "[ad_quotehtml $imarray(link)]\n" + if {[info exists iarray(width)]} { + set element [ad_quotehtml $iarray(width)] + append rss "$element\n" + } + append rss "\n" + + # now top level items + foreach item $items { + array unset iarray + array set iarray $item + append rss "\n" + set element [ad_quotehtml $iarray(title)] + append rss "$element\n" + append rss "[ad_quotehtml $iarray(link)]\n" + if {[info exists iarray(description)]} { + set element [ad_quotehtml $iarray(description)] + append rss "$element\n" + } + if {[info exists iarray(timestamp)]} { + set element [ad_quotehtml $iarray(timestamp)] + append rss "$element\n" + } + + append rss "\n" + } + + append rss "" + return $rss + +} + +ad_proc rss_gen_091 { + { + -channel_title "" + -channel_link "" + -channel_description "" + -channel_language "en-us" + -channel_copyright "" + -channel_managingEditor "" + -channel_webMaster "" + -channel_rating "" + -channel_pubDate "" + -channel_lastBuildDate "" + -channel_skipDays "" + -channel_skipHours "" + -image "" + -items "" + } +} { + generate an rss 0.91 xml feed +} { + + set rss "" + + if {[empty_string_p $channel_title]} { + error "argument channel_title not provided" + } + if {[empty_string_p $channel_link]} { + error "argument channel_link not provided" + } + if {[empty_string_p $channel_description]} { + error "argument channel_description not provided" + } + + append rss "\n" + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_title] + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_link] + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_description] + append rss "\n" + + append rss "" + append rss [ad_quotehtml $channel_language] + append rss "\n" + + if {![empty_string_p $channel_copyright]} { + append rss "" + append rss [ad_quotehtml $channel_copyright] + append rss "\n" + } + + if {![empty_string_p $channel_managingEditor]} { + append rss "" + append rss [ad_quotehtml $channel_managingEditor] + append rss "\n" + } + + if {![empty_string_p $channel_webMaster]} { + append rss "" + append rss [ad_quotehtml $channel_webMaster] + append rss "\n" + } + + if {![empty_string_p $channel_rating]} { + append rss "" + append rss [ad_quotehtml $channel_rating] + append rss "\n" + } + + if {![empty_string_p $channel_pubDate]} { + append rss "" + append rss [ad_quotehtml $channel_pubDate] + append rss "\n" + } + + if {![empty_string_p $channel_lastBuildDate]} { + append rss "" + append rss [ad_quotehtml $channel_lastBuildDate] + append rss "\n" + } + + append rss "" + append rss "http://backend.userland.com/stories/rss091" + append rss "\n" + + if {![empty_string_p $channel_skipDays]} { + append rss "" + append rss [ad_quotehtml $channel_skipDays] + append rss "\n" + } + + if {![empty_string_p $channel_skipHours]} { + append rss "" + append rss [ad_quotehtml $channel_skipHours] + append rss "\n" + } + + if {[empty_string_p $image]} { + set logo_rss "/graphics/openacs_logo_rss.gif" + set url [ad_parameter systemurl ""] + append url $logo_rss + set title $channel_title + set link $channel_link + set size [ns_gifsize [ns_url2file $logo_rss]] + set image [list \ + url $url \ + title $title \ + link $link \ + width [lindex $size 0] \ + height [lindex $size 1]] + } + + # image handling + append rss "\n" + array set iarray $image + + append rss "[ad_quotehtml $iarray(title)]\n" + append rss "$iarray(url)\n" + append rss "[ad_quotehtml $iarray(link)]\n" + if {[info exists iarray(width)]} { + set element [ad_quotehtml $iarray(width)] + append rss "$element\n" + } + if {[info exists iarray(height)]} { + set element [ad_quotehtml $iarray(height)] + append rss "$element\n" + } + if {[info exists iarray(description)]} { + set element [ad_quotehtml $iarray(description)] + append rss "$element\n" + } + + append rss "\n" + + # now do the items + foreach item $items { + array unset iarray + array set iarray $item + append rss "\n" + set element [ad_quotehtml $iarray(title)] + append rss "$element\n" + append rss "[ad_quotehtml $iarray(link)]\n" + if {[info exists iarray(description)]} { + set element [ad_quotehtml $iarray(description)] + if {[info exists iarray(timestamp)]} { + # if {[info exists iarray(timeformat)]} { + # set timeformat $iarray(timeformat) + # } else { + set timeformat "%B %e, %Y %H:%M%p %Z" + # } + set timestamp [clock format [clock scan $iarray(timestamp)] \ + -format $timeformat] + append element " $timestamp" + } + append rss "$element\n" + } + append rss "\n" + } + + append rss "\n" + append rss "\n" + + return $rss + +} + +ad_proc rss_gen { + { + -version .91 + -channel_title "" + -channel_link "" + -channel_description "" + -image "" + -items "" + -channel_language "en-us" + -channel_copyright "" + -channel_managingEditor "" + -channel_webMaster "" + -channel_rating "" + -channel_pubDate "" + -channel_lastBuildDate "" + -channel_skipDays "" + -channel_skipHours "" + } +} { +
+    Generates an RSS XML doc given channel information and item
+    information.  Supports versions .91 and 1.0.
+
+    Does not determine if field lengths are valid, nor does it
+    determine if field values are of the proper type.
+
+    Doesn't support textInput forms
+
+    Merely creates the XML doc.  GIGO and caveat emptor.
+
+    version is 0.91 or 1.0.  If not present, defaults to 0.91
+    
+    the default image is openacs/www/graphics/openacs_logo_rss.gif 
+
+    For 0.91, 
+    pubdate, copyright, lastbuildate, skipdays, skiphours,
+    webmaster, managingeditor fields,
+    if not specified are not included in the xml.
+
+    the image parameter is a property list of:
+      url $url title $title link $link 
+          [width $width] [height $height] [description $description]
+      where the elements within brackets are optional
+
+    items are a list of property lists, one for each item
+      title $title link $link description $description
+
+    Spec/channel docs url for 0.91 is
+    http://backend.userland.com/stories/rss091
+    
+    For 1.0
+    Spec can be found at
+    http://groups.yahoo.com/group/rss-dev/files/specification.html
+    The 1.0 spec is very primitive: my needs are primitive as of yet,
+    and I don't grok the rss 1.0 modules stuff as yet.  Whoops p'gazonga.
+    
+    
+} { + set rss "\n" + switch $version { + 100 - + 1.00 - + 1.0 - + 1 { + set rss [rss_gen_100 \ + -channel_title $channel_title \ + -channel_link $channel_link \ + -channel_description $channel_description \ + -image $image \ + -items $items \ + ] + } + default { + + set rss [rss_gen_091 \ + -channel_title $channel_title \ + -channel_link $channel_link \ + -channel_description $channel_description \ + -channel_language $channel_language \ + -channel_copyright $channel_copyright \ + -channel_managingEditor $channel_managingEditor \ + -channel_webMaster $channel_webMaster \ + -channel_rating $channel_rating \ + -channel_pubDate $channel_pubDate \ + -channel_lastBuildDate $channel_lastBuildDate \ + -channel_skipDays $channel_skipDays \ + -channel_skipHours $channel_skipHours \ + -image $image \ + -items $items \ + ] + + } + } + return $rss +} + +proc_doc rss_lang_widget {{selected_lang en}} { + creates an html-select field widget with lots of html language + choices in it +} { + foreach {value lang} { + af {Afrikaans} + sq {Albanian} + eu {Basque} + be {Belarusian} + bg {Bulgarian} + ca {Catalan} + zh-cn {Chinese (Simplified)} + zh-tw {Chinese (Traditional)} + hr {Croatian} + cs {Czech} + da {Danish} + nl {Dutch} + nl-be {Dutch (Belgium)} + nl-nl {Dutch (Netherlands)} + en {English} + en-au {English (Australia)} + en-bz {English (Belize)} + en-ca {English (Canada)} + en-ie {English (Ireland)} + en-jm {English (Jamaica)} + en-nz {English (New Zealand)} + en-ph {English (Phillipines)} + en-za {English (South Africa)} + en-tt {English (Trinidad)} + en-gb {English (United Kingdom)} + en-us {English (United States)} + en-zw {English (Zimbabwe)} + fo {Faeroese} + fi {Finnish} + fr {French} + fr-be {French (Belgium)} + fr-ca {French (Canada)} + fr-fr {French (France)} + fr-lu {French (Luxembourg)} + fr-mc {French (Monaco)} + fr-ch {French (Switzerland)} + gl {Galician} + gd {Gaelic} + de {German} + de-at {German (Austria)} + de-de {German (Germany)} + de-li {German (Liechtenstein)} + de-lu {German (Luxembourg)} + de-ch {German (Switzerland)} + el {Greek} + hu {Hungarian} + is {Icelandic} + in {Indonesian} + ga {Irish} + it {Italian} + it-it {Italian (Italy)} + it-ch {Italian (Switzerland)} + ja {Japanese} + ko {Korean} + mk {Macedonian} + no {Norwegian} + pl {Polish} + pt {Portuguese} + pt-br {Portuguese (Brazil)} + pt-pt {Portuguese (Portugal)} + ro {Romanian} + ro-mo {Romanian (Moldova)} + ro-ro {Romanian (Romania)} + ru {Russian} + ru-mo {Russian (Moldova)} + ru-ru {Russian (Russia)} + sr {Serbian} + sk {Slovak} + sl {Slovenian} + es {Spanish} + es-ar {Spanish (Argentina)} + es-bo {Spanish (Bolivia)} + es-cl {Spanish (Chile)} + es-co {Spanish (Colombia)} + es-cr {Spanish (Costa Rica)} + es-do {Spanish (Dominican Republic)} + es-ec {Spanish (Ecuador)} + es-sv {Spanish (El Salvador)} + es-gt {Spanish (Guatemala)} + es-hn {Spanish (Honduras)} + es-mx {Spanish (Mexico)} + es-ni {Spanish (Nicaragua)} + es-pa {Spanish (Panama)} + es-py {Spanish (Paraguay)} + es-pe {Spanish (Peru)} + es-pr {Spanish (Puerto Rico)} + es-es {Spanish (Spain)} + es-uy {Spanish (Uruguay)} + es-ve {Spanish (Venezuela)} + sv {Swedish} + sv-fi {Swedish (Finland)} + sv-se {Swedish (Sweden)} + tr {Turkish} + uk {Ukranian} + } { + + if {[string equal $value $selected_lang]} { + set selected SELECTED + } else { + set selected "" + } + + lappend options "