Index: openacs-4/packages/simulation/tcl/object-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/tcl/object-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/simulation/tcl/object-procs.tcl 7 Nov 2003 16:08:45 -0000 1.1 +++ openacs-4/packages/simulation/tcl/object-procs.tcl 10 Nov 2003 16:56:56 -0000 1.2 @@ -7,52 +7,146 @@ } namespace eval simulation::object {} +namespace eval simulation::object::xml {} -ad_proc -public simulation::object::schedule_generate_xml_file { - {-package_id ""} +ad_proc -private simulation::object::xml::file_sweeper {} { + Loop over all simulation package instances and re-generate + XML map files for them. + + @see simulation::object::xml::generate_file + + @author Peter Marklund } { -

- Schedules the proc simulation::object::generate_xml_file to be - executed now in its own thread. -

+ set simulation_package_ids [db_list simulation_package_ids { + select package_id + from apm_packages + where package_key = 'simulation' + }] -

- This proc needs to be invoked upon the create, edit, and delete - event for simulation objects that have the on_map_p attribute - set to true. It also needs to be invoked if the on_map_p attribute - is toggled from false to true for a sim object. -

+ ns_log Notice "Proc simulation::object::xml::file_sweeper executing with simulation_package_ids=$simulation_package_ids" + foreach package_id $simulation_package_ids { + generate_file -package_id $package_id + } + ns_log Notice "Finished executing simulation::object::xml::file_sweeper" +} - +ad_proc -private simulation::object::xml::generate_file { + {-package_id:required} +} { + Generate map XML document for the package. Compare the XML + document with any existing XML document for the package and + write the new document to the filesystem if it differs from + the existing document. Sends a notification if the file + was generated or if there were errors generating the file. + @see simulation::object::xml::get_doc + + @return 1 if a new XML file was written and 0 otherwise + @author Peter Marklund } { - if { [empty_string_p $package_id] } { - set package_id [ad_conn package_id] + set errors [list] + + set parameter_name "MapXmlFilePath" + set file_path [parameter::get -parameter $parameter_name -package_id $package_id] + + # An empty file_path signifies that no XML map file should be generated + if { [empty_string_p $file_path] } { + return } - ad_schedule_proc -thread t -once t 0 simulation::object::generate_xml_file -package_id $package_id + # file_path validity check + set file_path_error_prefix "Parameter simulation.$parameter_name for package $package_id has invalid value \"${file_path}\"." + if { ![regexp {^/} $file_path] } { + set error_message "$file_path_error_prefix It needs to start with /" + lappend errors $error_message + ns_log Error $error_message + } + if { ![file readable $file_path] } { + set error_message "$file_path_error_prefix The file is not readable" + lappend errors $error_message + ns_log Error $error_message + } + + set wrote_file_p 0 + with_catch errmsg { + + if { [llength $errors] == 0 } { + set old_xml_doc [template::util::read_file $file_path] + set new_xml_doc [get_doc -package_id $package_id] + set xml_changed_p [ad_decode [string compare $old_xml_doc $new_xml_doc] 0 0 1] + error hej + if { $xml_changed_p } { + template::util::write_file $file_path + set wrote_file_p 1 + } + } + } { + global errorInfo + set error_message "Generating XML file failed with error message: $errmsg\n\n$errorInfo" + ns_log Error $error_message + lappend errors $error_message + } + + if { $wrote_file_p || [llength $errors] > 0 } { + notify \ + -package_id $package_id \ + -file_path $file_path \ + -wrote_file_p $wrote_file_p \ + -errors $errors + } + + return $wrote_file_p } -ad_proc -public simulation::object::generate_xml_file { +ad_proc -private simulatation::object::xml::notify { {-package_id:required} + {-file_path:required} + {-wrote_file_p:required} + {-errors:required} } { -

- Re-generates (or generates for the first time) the XML file - containing information about all simulation objects that are - to be on the SIMBUILD flash map. -

+ Send a notification about the results of an XML file generation. @author Peter Marklund } { - ########## - # Get data to be written to file - ########## + set package_url "[ad_url][apm_package_url_from_id $package_id]" - # Get a list of names of tables storing the on_map_p attribute for - # items created in the given package + set subject "XML File generation results for package at ${package_url}" + + if { $wrote_file_p } { + append body "An XML file was written to file at \"$file_path\"." + } else { + append body "An XML file could not be written to file at \"$file_path\"." + } + + if { [llength $errors] > 0 } { + set all_errors [join $errors "\n\n"] + append body "\n\nThe following errors were encountered: + +$all_errors + +" + } + + # Send notification +} + +ad_proc -private simulation::object::xml::get_doc { + {-package_id:required} +} { + Generates XML for all relevant simulation objects in the given + package (that have on_map_p attribute set to true). + + @return An XML document + + @author Peter Marklund +} { + set full_package_url "[ad_url][apm_package_url_from_id $package_id]" + + # Get table names and id column names for the on_map_p attribute of each object type + # By using the multirow we avoid a nested db_foreach set parent_id [bcms::folder::get_id_by_package_id -parent_id 0] - set sim_table_lists [db_list select_sim_tables { + db_multirow -local sim_table_list select_sim_tables { select aot.table_name, aot.id_column from acs_object_types aot, @@ -64,110 +158,79 @@ where ci.parent_id = :parent_id and ci.content_type = aot.object_type ) - }] + } - foreach sim_table $sim_table_list { - set table_name [lindex $sim_table 0] - set id_column [lindex $sim_table 1] + # Open XML document + set xml_doc "\n\n" - set object_lists [db_list_of_lists select_on_map_objects " - select ci.item_id, - cr.content_type - cr.title, - ci.name, + # Object type loop. + template::multirow -local foreach sim_table_list { + ns_log Notice " + select ci.item_id as id, + cr.title as name, + ci.name as uri, cr.description, + ci.content_type, + (select min(ci2.name) + from cr_item_rels cir, + cr_items ci2 + where cir.item_id = ci.item_id + and cir.related_object_id = ci2.item_id + and cir.relation_tag = 'thumbnail') as thumbnail_uri from cr_items ci - cr_revisions cr + left outer join cr_item_rels cir on (cir.item_id = ci.item_id), + cr_revisions cr, $table_name st where st.on_map_p = 't' - and st.$id_column = ci.item_id + and st.$id_column = cr.revision_id and ci.live_revision = cr.revision_id and ci.parent_id = :parent_id - "] - } + order by ci.name + " + db_foreach select_on_map_objects " + select ci.item_id as id, + cr.title as name, + ci.name as uri, + cr.description, + ci.content_type, + (select min(ci2.name) + from cr_item_rels cir, + cr_items ci2 + where cir.item_id = ci.item_id + and cir.related_object_id = ci2.item_id + and cir.relation_tag = 'thumbnail') as thumbnail_uri + from cr_items ci + left outer join cr_item_rels cir on (cir.item_id = ci.item_id), + cr_revisions cr, + $table_name st + where st.on_map_p = 't' + and st.$id_column = cr.revision_id + and ci.live_revision = cr.revision_id + and ci.parent_id = :parent_id + order by ci.name + " { + set url "$full_package_url/object/$name" - ########## - # Generate XML document - ########## + if { [lsearch -exact {sim_location sim_prop sim_character} $content_type] != -1 } { + set thumbnail_url "${full_package_url}object-content/${thumbnail_uri}" + } else { + set thumbnail_url "" + } - set xml_doc " -" - foreach object_list $object_lists { - append xml_doc [generate_xml \ - -item_id [lindex $object_list 0] \ - -content_type [lindex $object_list 1] \ - -title [lindex $object_list 2] \ - -name [lindex $object_list 3] \ - -description [lindex $object_list 4]] - } - append xml_doc "" + append xml_doc " \n" + # Assuming var names are identical to XML tag names + set xml_tag_names {name url thumbnail_url description} + foreach tag_name $xml_tag_names { + append xml_doc " <${tag_name}>[ad_quotehtml [set ${tag_name}]]\n" + } + append xml_doc " \n" - ########## - # Write to file - ########## + } ;# End object loop - # TODO: make filepath a parameter - set file_path "/tmp/map-objects.xml" - set file_id [open $file_path w] - puts $file_id $xml_doc - close $catalog_file_id -} + } ;# End object type loop -ad_proc -public simulation::object::generate_xml { - {-item_id:required} - {-content_type ""} - {-title ""} - {-name ""} - {-description ""} -} { -

- Generate XML to be used by the CityBuild flash map for a certain - simulation object. Requires there to be an HTTP connection as it - uses ad_conn package_url to get the URL of the object. -

+ # Close XML document + append xml_doc "
\n" - @param item_id Stored in cr_items.item_id - @param content_type Stored in cr_items.content_type - @param title Stored in cr_revisions.title - @param name Stored in cr_items.name - @param description Stored in cr_revisions.description - - @author Peter Marklund -} { - # Set default values for optional args - set optional_args {content_type title name description} - foreach arg_name $optional_args { - if { [empty_string_p [set $arg_name]] } { - if { ![info exists item_info] } { - array set item_info [bcms::item::get_item -item_id $item_id -revision live] - } - - set $arg_name $item_info($arg_name) - } - } - - # Get object url and thumbnail url - set full_package_url "[ad_url]/[ad_conn package_url]" - set url "$full_package_url/object/$name" - if { [lsearch -exact {sim_location sim_prop sim_character} $content_type] != -1 } { - set thumbnail_list [bcms::item::list_related_items \ - -return_list \ - -item_id $item_id \ - -relation_tag thumbnail] - set thumbnail_uri [lindex [lindex $thumbnail_list 0] 1] - set thumbnail_url "$full_package_url/object-content/$thumbnail_uri" - } else { - set thumbnail_url "" - } - - # Create XML document - append flash_xml " - $item_id - [ad_quotehtml $name] - [ad_quotehtml $url] - [ad_quotehtml $thumbnail_url] - [ad_quotehtml $description] -" - - return $flash_xml + return $xml_doc }