Index: openacs-4/contrib/obsolete-packages/ticket-tracker/ticket-tracker.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker/ticket-tracker.info,v
diff -u -r1.7 -r1.8
--- openacs-4/contrib/obsolete-packages/ticket-tracker/ticket-tracker.info	23 Feb 2002 05:16:17 -0000	1.7
+++ openacs-4/contrib/obsolete-packages/ticket-tracker/ticket-tracker.info	16 Jan 2003 14:05:30 -0000	1.8
@@ -80,7 +80,6 @@
             <file type="content_page" path="www/admin/install/index.tcl"/>
             <file type="query_file" path="www/admin/install/index.xql"/>
             <file type="tcl_util" path="www/admin/install/set-sender.tcl"/>
-            <file type="content_page" path="www/admin/master.adp"/>
             <file type="query_file" db_type="oracle" path="www/admin/option-add-2-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="www/admin/option-add-2-postgresql.xql"/>
             <file type="content_page" path="www/admin/option-add-2.tcl"/>
@@ -122,7 +121,6 @@
             <file type="content_page" path="www/index.adp"/>
             <file type="content_page" path="www/index.tcl"/>
             <file type="query_file" path="www/index.xql"/>
-            <file type="content_page" path="www/master.adp"/>
             <file type="content_page" path="www/selection-bar.adp"/>
             <file type="content_page" path="www/selection-bar.tcl"/>
             <file type="query_file" path="www/selection-bar.xql"/>
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/ticket-add.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/ticket-add.tcl,v
diff -u -r1.4 -r1.5
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/ticket-add.tcl	6 Sep 2002 13:28:00 -0000	1.4
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/ticket-add.tcl	16 Jan 2003 14:06:07 -0000	1.5
@@ -19,7 +19,7 @@
         set message "
             Before you can add a ticket, you need to 
             <a href=admin/area-ae?[ttl_return_url_clause]>add a feature area</a> 
-            so the ticket can be categoried."
+            so the ticket can be categorized."
     } else {
         set message "
             Before you can add a ticket, you need an administrator
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.adp,v
diff -u -r1.2 -r1.3
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.adp	6 Sep 2002 13:28:02 -0000	1.2
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.adp	16 Jan 2003 14:06:29 -0000	1.3
@@ -1,6 +1,6 @@
-<master src="master">
+<master>
 <property name=title>Ticket Tracker Lite: Developers Notes</property>
-<property name=context>@context@</property>
+<property name=context>{{./} {ticket tracker lite}} {developer notes}</property>
 
 <p>By David Rodriguez (<a href=mailto:dvr@arsdigita.com>dvr@arsdigita.com</a>)
 
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.tcl'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp,v
diff -u -r1.2 -r1.3
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp	6 Sep 2002 13:28:02 -0000	1.2
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp	16 Jan 2003 14:06:29 -0000	1.3
@@ -1,6 +1,6 @@
-<master src="master">
+<master>
 <property name=title>Using the ticket tracker</property>
-<property name=context>@context@</property>
+<property name=context>{{./} {ticket tracker lite}} help</property>
 
 <p>The ticket tracker is a tool for development teams and their
 clients to organize bug reports and feature requests. 
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.tcl'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp,v
diff -u -r1.4 -r1.5
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp	6 Sep 2002 13:28:02 -0000	1.4
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp	16 Jan 2003 14:06:29 -0000	1.5
@@ -1,6 +1,6 @@
-<master src="master">
+<master>
 <property name=title>Ticket Tracker Lite</property>
-<property name=context>@context@</property>
+<property name=context>"ticket tracker lite"</property>
 
 <p>By David Rodriguez (<a href=mailto:dvr@arsdigita.com>dvr@arsdigita.com</a>)
 
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.tcl'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/packages/static-pages/static-pages.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/static-pages.info,v
diff -u -r1.12 -r1.13
--- openacs-4/packages/static-pages/static-pages.info	23 Sep 2002 23:32:34 -0000	1.12
+++ openacs-4/packages/static-pages/static-pages.info	16 Jan 2003 13:58:34 -0000	1.13
@@ -5,18 +5,18 @@
     <package-name>Static Pages</package-name>
     <pretty-plural>Static Pages</pretty-plural>
     <initial-install-p>f</initial-install-p>
-    <singleton-p>t</singleton-p>
+    <singleton-p>f</singleton-p>
 
-    <version name="4.2a" url="http://www.arsdigita.com/acs-repository/download/apm/static-pages-4.2a.apm">
+    <version name="4.3" url="http://openacs.org/">
     <database-support>
         <database>oracle</database>
         <database>postgresql</database>
     </database-support>
-        <owner url="mailto:bcalef@arsdigita.com">Brandoch Calef</owner>
-        <owner url="mailto:bcalef@arsdigita.com">Brandoch Calef</owner>
+        <owner url="mailto:dave@thedesignexperience.org">Dave Bauer</owner>
+        <owner url="http://www.piskorski.com">Andrew Piskorski</owner>
         <summary>Static Pages makes it possible to search and comment on static pages.</summary>
-        <release-date>2001-03-09</release-date>
-        <vendor url="http://www.arsdigita.com/">ArsDigita Corporation</vendor>
+        <release-date>2002-12-11</release-date>
+        <vendor url="http://openacs.org/">OpenACS</vendor>
         <description format="text/plain">Static Pages loads the static pages of a site into the database so that their contents are available to other packages, such as site-wide-search.  It also allows users to make comments on static pages.</description>
 
         <provides url="static-pages" version="4.2a"/>
@@ -34,17 +34,14 @@
             <file type="data_model_drop" db_type="postgresql" path="sql/postgresql/static-pages-drop.sql"/>
             <file type="data_model" db_type="postgresql" path="sql/postgresql/static-pages-sc-create.sql"/>
             <file type="data_model" db_type="postgresql" path="sql/postgresql/static-pages-sc-drop.sql"/>
-            <file type="data_model" db_type="postgresql" path="sql/postgresql/static-pages-sws-drop.sql"/>
-            <file type="data_model" db_type="postgresql" path="sql/postgresql/static-pages-sws.sql"/>
             <file type="package_spec" path="static-pages.info"/>
             <file type="tcl_init" path="tcl/static-pages-init.tcl"/>
             <file type="query_file" db_type="oracle" path="tcl/static-pages-procs-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="tcl/static-pages-procs-postgresql.xql"/>
             <file type="tcl_procs" path="tcl/static-pages-procs.tcl"/>
             <file type="query_file" path="tcl/static-pages-procs.xql"/>
-            <file type="data_model" db_type="oracle" path="tcl/static-pages-sc-create.sql"/>
-            <file type="query_file" db_type="postgresql" path="tcl/static-pages-sc-procs-postgresql.xql"/>
             <file type="tcl_procs" path="tcl/static-pages-sc-procs.tcl"/>
+            <file type="query_file" path="tcl/static-pages-sc-procs.xql"/>
             <file type="content_page" path="www/admin/commentability-contain.tcl"/>
             <file type="query_file" db_type="oracle" path="www/admin/commentability-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="www/admin/commentability-postgresql.xql"/>
@@ -53,7 +50,7 @@
             <file type="content_page" path="www/admin/commentability-toggle.tcl"/>
             <file type="content_page" path="www/admin/commentability.adp"/>
             <file type="content_page" path="www/admin/commentability.tcl"/>
-            <file type="query_file" path="www/admin/display-policy-toggle-orcale.xql"/>
+            <file type="query_file" path="www/admin/display-policy-toggle-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="www/admin/display-policy-toggle-postgresql.xql"/>
             <file type="content_page" path="www/admin/display-policy-toggle.tcl"/>
             <file type="content_page" path="www/admin/fs-scan-progress.tcl"/>
@@ -64,7 +61,6 @@
             <file type="content_page" path="www/admin/index.adp"/>
             <file type="content_page" path="www/admin/index.tcl"/>
             <file type="query_file" path="www/admin/index.xql"/>
-            <file type="content_page" path="www/admin/master.adp"/>
             <file type="documentation" path="www/doc/acs-admin-guide.html"/>
             <file type="documentation" path="www/doc/ad-doc.css"/>
             <file type="documentation" path="www/doc/dev-guide.html"/>
@@ -76,13 +72,14 @@
             <file type="documentation" path="www/doc/xml/requirements.xml"/>
             <file type="content_page" path="www/index.tcl"/>
             <file type="content_page" path="www/page-visit.tcl"/>
-            <file type="content_page" path="www/templates/static.adp"/>
             <file type="query_file" path="www/page-visit.xql"/>
+            <file type="content_page" path="www/templates/static.adp"/>
         </files>
         <parameters>
             <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="AllowedExtensions"  default="html htm" description="Enter the file extensions you want to have working with &quot;static-pages&quot;. Separate them with a single whitespace. (Case insensitive)."/>
             <parameter datatype="number"  min_n_values="1"  max_n_values="1"  name="TemplatingEnabledP"  default="0" description="Set this to 1 if you want the pages that are scanned by static-pages to be templated. Otherwise set it to 0."/>
             <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="TemplatePath"  default="/packages/static-pages/www/templates/static" description="If you want to activate templating of static pages, you must tell the system where to find the adp template. Leave out the initial / and don't forget the filename. (the path is relative to [acs_root_dir] and .adp is implied).]"/>
+            <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="fs_root"  default="/www" description="Root folder of Static Pages tree, relative to acs_root_dir server root."/>
         </parameters>
 
     </version>
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/static-page-pb.sql'.
Fisheye: No comparison available.  Pass `N' to diff?
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/static-page-ph.sql'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql,v
diff -u -r1.1 -r1.2
--- openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql	20 Apr 2001 20:51:22 -0000	1.1
+++ openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql	16 Jan 2003 13:59:05 -0000	1.2
@@ -48,6 +48,17 @@
 create index sp_folders_parent_id_idx on sp_folders(parent_id);
 create index sp_folders_package_id_idx on sp_folders(package_id);
 
+
+-- TODO: Why exactly do we need the sp_folders table to completely
+-- mirror the hierarchy in the Content Repository, rather than just
+-- using a small table to point to the root folders, the way File
+-- Storage does?  --atp@piskorski.com, 2001/08/26 21:30 EDT
+
+-- TODO: A root folder has a null sp_folders.parent_id, but we can't
+-- index nulls so may want to add a separate sp_root_folders table or
+-- something.  --atp@piskorski.com, 2001/08/26 22:47 EDT
+
+
 -- The title and content of each page will go into cr_revisions.  Here
 -- we record the filename.
 --
@@ -66,11 +77,17 @@
 			constraint static_pgs_show_cmnts_chk
 			check (show_comments_p in ('t','f'))
 );
+
 comment on table static_pages is '
 	Extends the cr_items table to hold information on static pages.
 '; 
 comment on column static_pages.filename is '
 	The full path of the file (e.g. /web/my_site/www/books/index.html).
+  --
+  No, not anymore.  As of c. 2001/10/30 changes by daveb, it is a
+  RELATIVE path, relative to the page root (server/www/).  As of now,
+  it is relative to the server root (server/).  --atp@piskorski.com,
+  2002/12/12 16:56 EST
 ';
 comment on column static_pages.folder_id is '
 	ID of folder containing page.
@@ -159,593 +176,8 @@
 	);
 end;
 /
+show errros
 
 
-create or replace package static_page as
-	function new (
-	-- /**
-	--  *  Creates a new content_item and content_revision for a
-	--  *  static page.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-02
-	--  **/
-		static_page_id	in static_pages.static_page_id%TYPE 
-					default null,
-		folder_id	in sp_folders.folder_id%TYPE,
-		filename	in static_pages.filename%TYPE default null,
-		title	in cr_revisions.title%TYPE default null,
-		content	in cr_revisions.content%TYPE default null,
-		show_comments_p	in static_pages.show_comments_p%TYPE default 't',
-		creation_date	in acs_objects.creation_date%TYPE 
-					default sysdate,
-		creation_user	in acs_objects.creation_user%TYPE 
-					default null,
-		creation_ip	in acs_objects.creation_ip%TYPE 
-					default null,
-		context_id	in acs_objects.context_id%TYPE 
-					default null
-	) return static_pages.static_page_id%TYPE;
-
-	procedure delete (
-	-- /**
-	--  *  Delete a static page, including the associated content_item.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-02
-	--  **/
-		static_page_id	in static_pages.static_page_id%TYPE
-	);
-
-	function get_root_folder (
-	-- /**
-	--  *  Returns the id of the root folder belonging to this package.
-	--  *  If none exists, one is created.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-22
-	--  **/
-		package_id	in apm_packages.package_id%TYPE
-	) return sp_folders.folder_id%TYPE;
-
-	function new_folder (
-	-- /**
-	--  *  Create a folder in the content_repository to hold files in
-	--  *  a particular directory.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-02
-	--  **/
-		folder_id	in sp_folders.folder_id%TYPE 
-					default null,
-		name	in cr_items.name%TYPE,
-		label	in cr_folders.label%TYPE,
-		description	in cr_folders.description%TYPE default null,
-		parent_id	in cr_items.parent_id%TYPE default null,
-		creation_date	in acs_objects.creation_date%TYPE 
-					default sysdate,
-		creation_user	in acs_objects.creation_user%TYPE 
-					default null,
-		creation_ip	in acs_objects.creation_ip%TYPE 
-					default null,
-		context_id	in acs_objects.context_id%TYPE 
-					default null
-	) return sp_folders.folder_id%TYPE;
-
-	procedure delete_folder (
-	-- /**
-	--  *  Delete a folder and all the folders and files it contains.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-02
-	--  **/
-		folder_id	in sp_folders.folder_id%TYPE
-	);
-
-	procedure delete_stale_items (
-	-- /**
-	--  *  Delete items that are in the content repository but not in
-	--  *  extant_files/extant_folders with the given session_id.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-02
-	--  **/
-		session_id	in sp_extant_files.session_id%TYPE,
-		package_id	in apm_packages.package_id%TYPE
-	);
-
-	procedure grant_permission (
-	-- /**
-	--  *  Grant a privilege on a file or folder, perhaps recursively.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-21
-	--  **/
-		item_id		in acs_permissions.object_id%TYPE,
-		grantee_id	in acs_permissions.grantee_id%TYPE,
-		privilege	in acs_permissions.privilege%TYPE,
-		recursive_p	in char
-	);
-
-	procedure revoke_permission (
-	-- /**
-	--  *  Revoke a privilege on a file or folder, perhaps recursively.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-21
-	--  **/
-		item_id		in acs_permissions.object_id%TYPE,
-		grantee_id	in acs_permissions.grantee_id%TYPE,
-		privilege	in acs_permissions.privilege%TYPE,
-		recursive_p	in char
-	);
-
-	function five_n_spaces (
-	-- /**
-	--  *  Return 5n nonbreaking spaces.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-27
-	--  **/
-		n	in integer
-	) return varchar2;
-
-	procedure set_show_comments_p (
-	-- /**
-	--  *  Establish whether the contents of a comment are displayed
-	--  *  on a particular page.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-23
-	--  **/
-		item_id		in acs_permissions.object_id%TYPE,
-		show_comments_p	in static_pages.show_comments_p%TYPE
-	);
-
-	function get_show_comments_p (
-	-- /**
-	--  *  Retrieve the comment display policy.
-	--  *
-	--  *  @author Brandoch Calef
-	--  *  @creation-date 2001-02-23
-	--  **/
-		item_id		in acs_permissions.object_id%TYPE
-	) return static_pages.show_comments_p%TYPE;
-	
-end static_page;
-/
-
-create or replace package body static_page as
-	function new (
-		static_page_id	in static_pages.static_page_id%TYPE 
-					default null,
-		folder_id	in sp_folders.folder_id%TYPE,
-		filename	in static_pages.filename%TYPE default null,
-		title	in cr_revisions.title%TYPE default null,
-		content	in cr_revisions.content%TYPE default null,
-		show_comments_p	in static_pages.show_comments_p%TYPE default 't',
-		creation_date	in acs_objects.creation_date%TYPE 
-					default sysdate,
-		creation_user	in acs_objects.creation_user%TYPE 
-					default null,
-		creation_ip	in acs_objects.creation_ip%TYPE 
-					default null,
-		context_id	in acs_objects.context_id%TYPE 
-					default null
-	) return static_pages.static_page_id%TYPE is
-		v_item_id	static_pages.static_page_id%TYPE;
-	begin
-		-- Create content item; this also makes the content revision.
-		-- One might be tempted to set the content_type to static_page,
-		-- But this would confuse site-wide-search, which expects to
-		-- see a content_type of content_revision.
-		v_item_id := content_item.new(
-			item_id	=> static_page.new.static_page_id,
-			parent_id	=> static_page.new.folder_id,
-			name	=> static_page.new.filename,
-			title	=> static_page.new.title,
-			mime_type	=> 'text/html',
-			creation_date	=> static_page.new.creation_date,
-			creation_user	=> static_page.new.creation_user,
-			creation_ip	=> static_page.new.creation_ip,
-			context_id	=> static_page.new.context_id,
-			is_live	=> 't',
-			data	=> static_page.new.content
-		);
-
-		-- We want to be able to have non-commentable folders below
-		-- commentable folders.  We can't do this if we leave security
-		-- inheritance enabled.
-		--
-		update acs_objects set security_inherit_p = 'f' 
-			where object_id = v_item_id;
-
-		-- Copy permissions from the parent:
-		for permission_row in (
-			select grantee_id,privilege from acs_permissions
-				where object_id = folder_id
-		) loop
-			acs_permission.grant_permission(
-				object_id => v_item_id,
-				grantee_id => permission_row.grantee_id,
-				privilege => permission_row.privilege
-			);
-		end loop;
-
-		-- Insert row into static_pages:
-		insert into static_pages
-			(static_page_id, filename, folder_id, show_comments_p)
-		values (
-			v_item_id, 
-			static_page.new.filename,
-			static_page.new.folder_id,
-			static_page.new.show_comments_p
-		);
-
-		return v_item_id;
-	end;
-
-	procedure delete (
-		static_page_id	in static_pages.static_page_id%TYPE
-	) is
-	begin
-		-- Delete all permissions on this page:
-		delete from acs_permissions where object_id = static_page_id;
-
-		-- Drop all comments on this page.  general-comments doesn't have
-		-- a comment.delete() function, so I just do this (see the
-		-- general-comments drop script):
-		for comment_row in (
-			select comment_id from general_comments 
-			where object_id = static_page_id
-		) loop
-			delete from images
-			where image_id in (
-				select latest_revision
-				from cr_items
-				where parent_id = comment_row.comment_id
-			);
-
-			acs_message.delete(comment_row.comment_id);
-		end loop;
-
-		-- Delete the page.
-		-- WE SHOULDN'T NEED TO DO THIS: CONTENT_ITEM.DELETE SHOULD TAKE CARE OF
-		-- DELETING FROM STATIC PAGES.
-		delete from static_pages where static_page_id = static_page.delete.static_page_id;
-		content_item.delete(static_page_id);
-	end;
-
-	function get_root_folder (
-		package_id	in apm_packages.package_id%TYPE
-	) return sp_folders.folder_id%TYPE is
-		folder_exists_p	integer;
-		folder_id	sp_folders.folder_id%TYPE;
-	begin
-		-- If there isn't a root folder for this package, create one.
-		-- Otherwise, just return its id.
-		select count(*) into folder_exists_p from dual where exists (
-			select 1 from sp_folders 
-			where package_id = static_page.get_root_folder.package_id
-			and parent_id is null
-		);
-
-		if folder_exists_p = 0 then
-			folder_id := static_page.new_folder (
-				name => 'sp_root',
-				label => 'sp_root'
-			);
-
-			update sp_folders 
-				set package_id = static_page.get_root_folder.package_id
-				where folder_id = static_page.get_root_folder.folder_id;
-
-			acs_permission.grant_permission (
-				object_id => folder_id,
-				grantee_id => acs.magic_object_id('the_public'),
-				privilege => 'general_comments_create'
-			);
-			-- The comments will inherit read permission from the pages,
-			-- so the public should be able to read the static pages.
-			acs_permission.grant_permission (
-				object_id => folder_id,
-				grantee_id => acs.magic_object_id('the_public'),
-				privilege => 'read'
-			);
-		else
-			select folder_id into folder_id from sp_folders
-			where package_id = static_page.get_root_folder.package_id
-			and parent_id is null;
-		end if;
-
-		return folder_id;
-	end get_root_folder;
-
-
-	function new_folder (
-		folder_id	in sp_folders.folder_id%TYPE 
-					default null,
-		name	in cr_items.name%TYPE,
-		label	in cr_folders.label%TYPE,
-		description	in cr_folders.description%TYPE default null,
-		parent_id	in cr_items.parent_id%TYPE default null,
-		creation_date	in acs_objects.creation_date%TYPE 
-					default sysdate,
-		creation_user	in acs_objects.creation_user%TYPE 
-					default null,
-		creation_ip	in acs_objects.creation_ip%TYPE 
-					default null,
-		context_id	in acs_objects.context_id%TYPE 
-					default null
-	) return sp_folders.folder_id%TYPE is
-		v_folder_id	sp_folders.folder_id%TYPE;
-		v_parent_id	cr_items.parent_id%TYPE;
-		v_package_id	apm_packages.package_id%TYPE;
-	begin
-		if parent_id is null then
-			v_parent_id := 0;
-		else
-			v_parent_id := parent_id;
-		end if;
-
-		v_folder_id := content_folder.new (
-			name	=> static_page.new_folder.name,
-			label	=> static_page.new_folder.label,
-			folder_id	=> static_page.new_folder.folder_id,
-			parent_id	=> v_parent_id,
-			description	=> static_page.new_folder.description,
-			creation_date	=> static_page.new_folder.creation_date,
-			creation_user	=> static_page.new_folder.creation_user,
-			creation_ip	=> static_page.new_folder.creation_ip,
-			context_id	=> static_page.new_folder.context_id
-		);
-
-		if parent_id is not null then
-			-- Get the package_id from the parent:
-			select package_id into v_package_id from sp_folders
-				where folder_id = static_page.new_folder.parent_id;
-
-			insert into sp_folders (folder_id, parent_id, package_id)
-				values (v_folder_id, parent_id, v_package_id);
-
-			update acs_objects set security_inherit_p = 'f'
-				where object_id = v_folder_id;
-
-			-- Copy permissions from the parent:
-			for permission_row in (
-				select grantee_id,privilege from acs_permissions
-					where object_id = parent_id
-			) loop
-				acs_permission.grant_permission(
-					object_id => v_folder_id,
-					grantee_id => permission_row.grantee_id,
-					privilege => permission_row.privilege
-				);
-			end loop;
-		else
-			insert into sp_folders (folder_id, parent_id)
-				values (v_folder_id, parent_id);
-
-		-- if it's a root folder, allow it to contain static pages and
-		-- other folders (subfolders will inherit these properties)
-			content_folder.register_content_type (
-				folder_id => v_folder_id,
-				content_type => 'static_page'
-			);
-			content_folder.register_content_type (
-				folder_id => v_folder_id,
-				content_type => 'content_revision'
-			);
-			content_folder.register_content_type (
-				folder_id => v_folder_id,
-				content_type => 'content_folder'
-			);
-		end if;
-
-		return v_folder_id;
-	end;
-
-	procedure delete_folder (
-		folder_id	in sp_folders.folder_id%TYPE
-	) is
-	begin
-		for folder_row in (
-			select folder_id from (
-				select folder_id,level as path_depth from sp_folders
-				start with folder_id = static_page.delete_folder.folder_id
-				connect by parent_id = prior folder_id
-			) order by path_depth desc
-		) loop
-			for page_row in (
-				select static_page_id from static_pages
-				where folder_id = folder_row.folder_id
-			) loop
-				static_page.delete(page_row.static_page_id);
-			end loop;
-
-			delete from sp_folders where folder_id = folder_row.folder_id;
-			content_folder.delete(folder_row.folder_id);
-		end loop;
-	end;
-
-	procedure delete_stale_items (
-		session_id	in sp_extant_files.session_id%TYPE,
-		package_id	in apm_packages.package_id%TYPE
-	) is
-		root_folder_id	sp_folders.folder_id%TYPE;
-	begin
-		root_folder_id := static_page.get_root_folder(package_id);
-
-		-- First delete all files that are descendants of the root folder
-		-- but aren't in sp_extant_files:
-		--
-		for stale_file_row in (
-			select static_page_id from static_pages
-			where folder_id in (
-				select folder_id from sp_folders
-				start with folder_id = root_folder_id
-				connect by parent_id = prior folder_id
-			) and static_page_id not in (
-				select static_page_id
-				from sp_extant_files
-				where session_id = static_page.delete_stale_items.session_id
-			)
-		) loop
-			static_page.delete(stale_file_row.static_page_id);
-		end loop;
-
-		-- Now delete all folders that aren't in sp_extant_folders.  There are two
-		-- views created on the fly here: dead (all descendants of the root
-		-- folder not in sp_extant_folders) and path (each folder and its depth).
-		-- They are joined together to get the depth of all the folders that
-		-- need to be deleted.  The root folder is excluded because it won't
-		-- show up in the filesystem search, so it will be missing from
-		-- sp_extant_folders.
-		--
-		for stale_folder_row in (
-			select dead.folder_id from
-			(select folder_id from sp_folders
-				where (folder_id) not in (
-					select folder_id
-					from sp_extant_folders
-					where session_id = static_page.delete_stale_items.session_id
-				)
-			) dead,
-			(select folder_id,level as depth from sp_folders
-				start with folder_id = root_folder_id
-				connect by parent_id = prior folder_id
-			) path
-			where dead.folder_id = path.folder_id 
-				and dead.folder_id <> root_folder_id
-			order by path.depth desc
-		) loop
-			delete from sp_folders
-			where folder_id = stale_folder_row.folder_id;
-
-			content_folder.delete(stale_folder_row.folder_id);
-		end loop;
-	end delete_stale_items;
-
-	procedure grant_permission (
-		item_id		in acs_permissions.object_id%TYPE,
-		grantee_id	in acs_permissions.grantee_id%TYPE,
-		privilege	in acs_permissions.privilege%TYPE,
-		recursive_p	in char
-	) is
-	begin
-		if recursive_p = 't' then
-			-- For each folder that is a descendant of item_id, grant.
-			for folder_row in (
-				select folder_id from sp_folders
-				start with folder_id = item_id
-				connect by parent_id = prior folder_id
-			) loop
-				acs_permission.grant_permission(
-					object_id => folder_row.folder_id,
-					grantee_id => static_page.grant_permission.grantee_id,
-					privilege => static_page.grant_permission.privilege
-				);
-			end loop;
-			-- For each file that is a descendant of item_id, grant.
-			for file_row in (
-				select static_page_id from static_pages	
-				where folder_id in (
-					select folder_id from sp_folders 
-					start with folder_id = item_id
-					connect by parent_id = prior folder_id
-				)
-			) loop
-				acs_permission.grant_permission(
-					object_id => file_row.static_page_id,
-					grantee_id => static_page.grant_permission.grantee_id,
-					privilege => static_page.grant_permission.privilege
-				);
-			end loop;
-		else
-			acs_permission.grant_permission(
-				object_id => item_id,
-				grantee_id => static_page.grant_permission.grantee_id,
-				privilege => static_page.grant_permission.privilege
-			);
-		end if;
-	end grant_permission;
-
-	procedure revoke_permission (
-		item_id		in acs_permissions.object_id%TYPE,
-		grantee_id	in acs_permissions.grantee_id%TYPE,
-		privilege	in acs_permissions.privilege%TYPE,
-		recursive_p	in char
-	) is
-	begin
-		if recursive_p = 't' then
-			-- For each folder that is a descendant of item_id, revoke.
-			for folder_row in (
-				select folder_id from sp_folders
-				start with folder_id = item_id
-				connect by parent_id = prior folder_id
-			) loop
-				acs_permission.revoke_permission(
-					object_id => folder_row.folder_id,
-					grantee_id => static_page.revoke_permission.grantee_id,
-					privilege => static_page.revoke_permission.privilege
-				);
-			end loop;
-			-- For each file that is a descendant of item_id, revoke.
-			for file_row in (
-				select static_page_id from static_pages	
-				where folder_id in (
-					select folder_id from sp_folders 
-					start with folder_id = item_id
-					connect by parent_id = prior folder_id
-				)
-			) loop
-				acs_permission.revoke_permission(
-					object_id => file_row.static_page_id,
-					grantee_id => static_page.revoke_permission.grantee_id,
-					privilege => static_page.revoke_permission.privilege
-				);
-			end loop;
-		else
-			acs_permission.revoke_permission(
-				object_id => item_id,
-				grantee_id => static_page.revoke_permission.grantee_id,
-				privilege => static_page.revoke_permission.privilege
-			);
-		end if;
-	end revoke_permission;
-
-	function five_n_spaces (
-		n	in integer
-	) return varchar2 is
-		space_string	varchar2(400);
-	begin
-		space_string := '';
-		for i in 1..n loop
-			space_string := space_string || '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
-		end loop;
-		return space_string;
-	end five_n_spaces;
-
-	procedure set_show_comments_p (
-		item_id		in acs_permissions.object_id%TYPE,
-		show_comments_p	in static_pages.show_comments_p%TYPE
-	) is
-        begin
-		update static_pages
-		set show_comments_p = static_page.set_show_comments_p.show_comments_p
-		where static_page_id = static_page.set_show_comments_p.item_id;
-	end;
-
-	function get_show_comments_p (
-		item_id		in acs_permissions.object_id%TYPE
-	) return static_pages.show_comments_p%TYPE is
-		v_show_comments_p	static_pages.show_comments_p%TYPE;
-	begin
-		select show_comments_p into v_show_comments_p from static_pages
-		where static_page_id = static_page.get_show_comments_p.item_id;
-
-		return v_show_comments_p;
-	end;
-
-end static_page;
-/
+@static-page-ph.sql
+@static-page-pb.sql
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/upgrade/upgrade-4.2a-4.3.sql'.
Fisheye: No comparison available.  Pass `N' to diff?
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/postgresql/static-page-pb.sql'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql,v
diff -u -r1.18 -r1.19
--- openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql	9 Dec 2001 04:21:58 -0000	1.18
+++ openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql	16 Jan 2003 14:00:21 -0000	1.19
@@ -254,589 +254,6 @@
 		'varchar(500)'		-- column_spec   
         );
 
--- create or replace package body static_page as
-create	function static_page__new (
-                integer, 	-- static_page_id	in static_pages.static_page_id%TYPE
-                         	--               default null,
-                integer, 	-- folder_id	in sp_folders.folder_id%TYPE,
-                varchar, 	-- filename	in static_pages.filename%TYPE default null,
-                varchar, 	-- title	in cr_revisions.title%TYPE default null,
-                text,           -- content	in cr_revisions.content%TYPE default null,
-                boolean, 	-- show_comments_p	in static_pages.show_comments_p%TYPE default 't',
-                timestamp, 	-- creation_date	in acs_objects.creation_date%TYPE
-                           	--             default sysdate,
-                integer, 	-- creation_user	in acs_objects.creation_user%TYPE
-                         	--               default null,
-                varchar, 	-- creation_ip	in acs_objects.creation_ip%TYPE
-                                --        default null,
-                integer, 	-- context_id	in acs_objects.context_id%TYPE
-                                --        default null
-		integer		-- mtime
-        ) returns integer as '
-	declare
-                p_static_page_id        alias for $1;
-                p_folder_id             alias for $2;
-                p_filename              alias for $3;
-                p_title                 alias for $4;
-                p_content               alias for $5;
-                p_show_comments_p       alias for $6;
-                p_creation_date         alias for $7;
-                p_creation_user         alias for $8;
-                p_creation_ip           alias for $9;
-                p_context_id            alias for $10;
-		p_mtime			alias for $11;
 
-                v_item_id	        static_pages.static_page_id%TYPE;
-                v_permission_row        RECORD;
-		v_revision_id		integer;
-		v_is_live		boolean default ''t'';
-		v_mime_type		cr_revisions.mime_type%TYPE default ''text/html'';
-		v_storage_type		cr_items.storage_type%TYPE default ''file'';
-        begin
-                -- Create content item; this also makes the content revision.
-                -- One might be tempted to set the content_type to static_page,
-                -- But this would confuse site-wide-search, which expects to
-                -- see a content_type of content_revision.
-		
-                v_item_id := content_item__new(
-                        p_static_page_id,               -- item_id
-			p_filename,                     -- name		
-			p_folder_id,                    -- parent_id
-                        p_title,                        -- title
-                        p_creation_date,                -- creation_date
-                        p_creation_user,                -- creation_user
-                        p_context_id,                   -- context_id
-                        p_creation_ip,                  -- creation_ip
-                        v_is_live,                          -- is_live
-                        v_mime_type,                  -- mime_type
-			p_content,                       -- text
-			v_storage_type,			 -- storage_type
-			FALSE,				 -- security_inherit_p
-			''STATIC_PAGES'',		-- storage_area_key
-			''content_item'',		 -- item subtype
-			''static_page''			 -- content_type
-                );
-
-
-                -- We want to be able to have non-commentable folders below
-                -- commentable folders.  We can''t do this if we leave security
-                -- inheritance enabled.
-                --
--- uses overloaded content_item__new and acs_object__new to set
--- security_inherit_p to ''f'' DaveB
---                update acs_objects set security_inherit_p = ''f''
---                        where object_id = v_item_id;
-
-                -- Copy permissions from the parent:
-                for v_permission_row in 
-                        select grantee_id,privilege from acs_permissions
-                                where object_id = p_folder_id
-                 loop
-                        perform acs_permission__grant_permission(
-                                v_item_id,                      -- object_id
-                                v_permission_row.grantee_id,    -- grantee_id
-                                v_permission_row.privilege      -- privilege
-                        );
-                end loop;
-
-                -- Insert row into static_pages:
-                insert into static_pages
-                        (static_page_id, filename, folder_id, show_comments_p, mtime)
-                values (
-                        v_item_id,
-                        p_filename,
-                        p_folder_id,
-                        p_show_comments_p,
-			p_mtime
-                );
-
-                return v_item_id;
-end;' language 'plpgsql';
-
-create	function static_page__new (
-
-                integer, 	-- folder_id	in sp_folders.folder_id%TYPE,
-                varchar, 	-- filename	in static_pages.filename%TYPE default null,
-                varchar, 	-- title	in cr_revisions.title%TYPE default null
-		integer		-- mtime
-        ) returns integer as '
-	declare
-                p_folder_id             alias for $1;
-                p_filename              alias for $2;
-                p_title                 alias for $3;
-		p_mtime			alias for $4;
-               
-	        v_static_page_id	static_pages.static_page_id%TYPE;	       
-                v_item_id	        static_pages.static_page_id%TYPE;
-
-        begin
-		return static_page__new (
-			   NULL,	       -- static_page_id
-			   p_folder_id,	       -- folder_id
-			   p_filename,	       -- filename
-			   p_title,	       -- title
-			   NULL,	       -- content
-			   ''t'',	       -- show_comments_p
-			   now(),	       -- creation_date
-			   NULL,	       -- creation_user
-			   NULL,	       -- creation_ip
-			   NULL,	       -- conext_id
-			   p_mtime	       -- mtime
-			   );
-	       
-end;' language 'plpgsql';
-
-
-create	function static_page__delete (
-                integer         -- static_page_id in static_pages.static_page_id%TYPE
-        ) returns integer as '
-        declare
-                p_static_page_id        alias for $1;
-                v_comment_row           RECORD;
-		v_rec_affected		integer;
-		v_static_page_id	integer;
-        begin
-                -- Delete all permissions on this page:
-
-	delete from acs_permissions where object_id = p_static_page_id;
-
-                -- Drop all comments on this page.  general-comments doesn''t have
-                -- a comment.delete() function, so I just do this (see the
-                -- general-comments drop script):
-
-		for v_comment_row in 
-                        select comment_id from general_comments
-                        where object_id = p_static_page_id
-                 loop
-                        delete from images
-                        where image_id in (
-                                select latest_revision
-                                from cr_items
-                                where parent_id = v_comment_row.comment_id
-                       );
-
-                        PERFORM acs_message__delete(v_comment_row.comment_id);
-                end loop;
-
-                -- Delete the page.
-                -- WE SHOULDN''T NEED TO DO THIS: CONTENT_ITEM.DELETE SHOULD TAKE CARE OF
-                -- DELETING FROM STATIC PAGES.
-
-	delete from static_pages where static_page_id = p_static_page_id;
-
-	GET DIAGNOSTICS v_rec_affected = ROW_COUNT;
-	RAISE NOTICE ''*** Number of rows deleted: %'',v_rec_affected;
-	select into v_static_page_id static_page_id from static_pages where static_page_id = p_static_page_id;
-	GET DIAGNOSTICS v_rec_affected = ROW_COUNT;
-	RAISE NOTICE ''*** selected % rows still in static_pages'',v_rec_affected;
-
-
-	PERFORM content_item__delete(p_static_page_id);
-return 0;
-end;' language 'plpgsql';
-
-create	function static_page__get_root_folder (
-                integer         -- package_id	in apm_packages.package_id%TYPE
-        ) returns integer as '
-        declare
-                p_package_id            alias for $1;
-                v_folder_exists_p	integer;
-                v_folder_id	        sp_folders.folder_id%TYPE;
-		v_rows			integer;
-begin
-                -- If there isn''t a root folder for this package, create one.
-                -- Otherwise, just return its id.
-                select count(*) into v_folder_exists_p where exists (
-                        select 1 from sp_folders
-                        where package_id = p_package_id
-                        and parent_id is null
-                );
-
-                if v_folder_exists_p = 0 then
-
-                        v_folder_id := static_page__new_folder (
-                                null,
-				''sp_root'',      -- name
-                                ''sp_root'',       -- label
-				null,
-				null,
-				null,
-				null,
-				null,
-				null
-                        );
-
-                        update sp_folders
-                                set package_id = p_package_id
-                                where folder_id = v_folder_id;
-
-                        PERFORM acs_permission__grant_permission (
-                                v_folder_id,                            -- object_id
-                                acs__magic_object_id(''the_public''),   -- grantee_id
-                                ''general_comments_create''             -- privilege
-                        );
-                        -- The comments will inherit read permission from the pages,
-                        -- so the public should be able to read the static pages.
-                        PERFORM acs_permission__grant_permission (
-                                v_folder_id,                            -- object_id
-                                acs__magic_object_id(''the_public''),   -- grantee_id
-                                ''read''                                  -- privilege
-                        );
-                else
-                        select folder_id into v_folder_id from sp_folders
-                        where package_id = p_package_id
-                        and parent_id is null;
-                end if;
-
-                return v_folder_id;
-end;' language 'plpgsql';
-
-create	function static_page__new_folder (
-                integer,        -- folder_id	in sp_folders.folder_id%TYPE
-                                --        default null,
-                varchar,        -- name	in cr_items.name%TYPE,
-                varchar,        -- label	in cr_folders.label%TYPE,
-                text,           -- description	in cr_folders.description%TYPE default null,
-                integer,        -- parent_id	in cr_items.parent_id%TYPE default null,
-                timestamp,      -- creation_date	in acs_objects.creation_date%TYPE
-                                --        default sysdate,
-                integer,        -- creation_user	in acs_objects.creation_user%TYPE
-                                --        default null,
-                varchar,        -- creation_ip	in acs_objects.creation_ip%TYPE
-                                --        default null,
-                integer         -- context_id	in acs_objects.context_id%TYPE
-                                --        default null
-        ) returns integer as '
-        declare
-                p_folder_id       alias for $1;
-                p_name            alias for $2;
-                p_label           alias for $3;
-                p_description     alias for $4;
-                p_parent_id       alias for $5;
-                p_creation_date   alias for $6;
-                p_creation_user   alias for $7;
-                p_creation_ip     alias for $8;
-                p_context_id      alias for $9;
-
-                v_folder_id	        sp_folders.folder_id%TYPE;
-                v_parent_id	        cr_items.parent_id%TYPE;
-                v_package_id	        apm_packages.package_id%TYPE;
-                v_creation_date         acs_objects.creation_date%TYPE;
-                v_permission_row        RECORD;
-        begin
-                if p_creation_date is null then
-                        v_creation_date := now();
-                else
-                        v_creation_date := p_creation_date;
-                end if;
-
-                if p_parent_id is null then
-                        v_parent_id := 0;
-                else
-                        v_parent_id := p_parent_id;
-                end if;
-
-                v_folder_id := content_folder__new (
-                        p_name,            -- name
-                        p_label,           -- label
-                        p_description,     -- description		
-                        v_parent_id,       -- parent_id
-                        p_context_id,      -- context_id
-			p_folder_id,       -- folder_id
-                        v_creation_date,   -- creation_date
-                        p_creation_user,   -- creation_user
-                        p_creation_ip,     -- creation_ip
-			''f''		-- secuity_inherit_p	
-
-                );
-
-                if p_parent_id is not null then
-                        -- Get the package_id from the parent:
-                        select package_id into v_package_id from sp_folders
-                                where folder_id = p_parent_id;
-
-                        insert into sp_folders (folder_id, parent_id, package_id)
-                                values (v_folder_id, p_parent_id, v_package_id);
-
---                        update acs_objects set security_inherit_p = ''f''
---                                where object_id = v_folder_id;
-
-                        -- Copy permissions from the parent:
-                        for v_permission_row in 
-                                select * from acs_permissions
-                                        where object_id = p_parent_id
-                         loop
-                                perform acs_permission__grant_permission(
-                                        v_folder_id,                    -- object_id
-                                        v_permission_row.grantee_id,    -- grantee_id
-                                        v_permission_row.privilege      -- privilege
-                                );
-                        end loop;
-                else
-                        insert into sp_folders (folder_id, parent_id)
-                                values (v_folder_id, p_parent_id);
-
-                -- if it''s a root folder, allow it to contain static pages and
-                -- other folders (subfolders will inherit these properties)
-                PERFORM  content_folder__register_content_type (
-                                v_folder_id,              -- folder_id
-                                ''static_page'',           -- content_type
-				''f''
-                        );
-                PERFORM  content_folder__register_content_type (
-                                v_folder_id,            -- folder_id
-                                ''content_revision'',      -- content_type
-				''f''
-                        );
-                PERFORM  content_folder__register_content_type (
-                                v_folder_id,            -- folder_id
-                                ''content_folder'',      -- content_type
-				''f''
-                        );
-                end if;
-
-                return v_folder_id;
-end;' language 'plpgsql';
-
-create	function static_page__delete_folder (
-                integer         -- folder_id	in sp_folders.folder_id%TYPE
-        ) returns integer as '
-        declare
-                p_folder_id     alias for $1;
-                v_folder_row    RECORD;
-                v_page_row      RECORD;
-        begin
-                for v_folder_row in
-                  select s1.folder_id, tree_level(s1.tree_sortkey) as path_depth
-                  from sp_folders s1, sp_folders s2
-                  where s2.folder_id = p_folder_id
-		    and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                  order by path_depth desc
-                 loop
-                        for v_page_row in 
-                                select static_page_id from static_pages
-                                where folder_id = v_folder_row.folder_id
-                         loop
-                             PERFORM static_page__delete(v_page_row.static_page_id);
-                        end loop;
-
-                        delete from sp_folders where folder_id = v_folder_row.folder_id;
-                        PERFORM content_folder__delete(v_folder_row.folder_id);
-                end loop;
-return 0;
-end;' language 'plpgsql';
-
-create	function static_page__delete_stale_items (
-                integer,	-- session_id	in sp_extant_files.session_id%TYPE,
-                integer		-- package_id	in apm_packages.package_id%TYPE
-        ) returns integer as '
-	declare
-                p_session_id	        alias for $1;
-                p_package_id	        alias for $2;
-                v_root_folder_id	sp_folders.folder_id%TYPE;
-		v_stale_file_row        RECORD;
-		v_stale_folder_row      RECORD;
-        begin
-                v_root_folder_id := static_page__get_root_folder(p_package_id);
-
-           -- First delete all files that are descendants of the root folder
-           -- but aren''t in sp_extant_files
-                
-	for v_stale_file_row in 
-	   select sp.static_page_id 
-           from static_pages sp, sp_folders s1, sp_folders s2
-	   where sp.folder_id = s1.folder_id
-             and s2.folder_id = v_root_folder_id
-             and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-	     and not exists (select 1
-                             from sp_extant_files sef
-                             where sef.session_id = p_session_id
-                             and sp.static_page_id = sef.static_page_id)
-	loop
-		PERFORM static_page__delete(v_stale_file_row.static_page_id);
-	end loop;
-
--- Now delete all folders that aren''t in sp_extant_folders.  There are two
--- views created on the fly here: dead (all descendants of the root
--- folder not in sp_extant_folders) and path (each folder and its depth).
--- They are joined together to get the depth of all the folders that
--- need to be deleted.  The root folder is excluded because it won''t
--- show up in the filesystem search, so it will be missing from
--- sp_extant_folders.
-
-		for v_stale_folder_row in 
-                        select dead.folder_id  from
-                        (select folder_id from sp_folders
-                                where folder_id not in (
-                                        select folder_id
-                                        from sp_extant_folders
-                                        where session_id = p_session_id
-                                )
-                        ) dead,
-                        (select s1.folder_id,tree_level(s1.tree_sortkey) as depth
-                         from sp_folders s1, sp_folders s2
-                         where s2.folder_id = v_root_folder_id
-                           and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                        ) path
-                        where dead.folder_id = path.folder_id
-                                and dead.folder_id <> v_root_folder_id
-                        order by path.depth desc
-                 loop
-		delete from sp_folders
-                        where folder_id = v_stale_folder_row.folder_id;
-                        perform content_folder__delete(v_stale_folder_row.folder_id);
-                end loop;
-
-return 0;
-end;' language 'plpgsql';
-
- 
-create	function static_page__grant_permission (
-                integer,	-- item_id in acs_permissions.object_id%TYPE,
-                integer,	-- grantee_id	in acs_permissions.grantee_id%TYPE,
-                varchar,	-- privilege	in acs_permissions.privilege%TYPE,
-                boolean		-- recursive_p	in char
-        ) returns integer as '
-	declare
-                p_item_id	alias for $1;
-                p_grantee_id	alias for $2;
-                p_privilege	alias for $3;
-                p_recursive_p	alias for $4;
-		v_file_row	RECORD;
-		v_folder_row	RECORD;
-        begin
-                if p_recursive_p = ''t'' then
-                        -- For each folder that is a descendant of item_id, grant.
-                        for v_folder_row in 
-                          select s1.folder_id from sp_folders s1, sp_folders s2
-                          where s2.folder_id = p_item_id
-                            and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                         loop
-                                perform acs_permission__grant_permission(
-				v_folder_row.folder_id,	-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                                );
-                        end loop;
-                        -- For each file that is a descendant of item_id, grant.
-                        for v_file_row in 
-                          select sp.static_page_id
-                          from static_pages sp, sp_folders s1, sp_folders s2
-                          where sp.folder_id = s1.folder_id
-                            and s2.folder_id = p_item_id
-                            and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                         loop
-                                perform acs_permission__grant_permission(
-				v_file_row.static_page_id,	-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                                );
-                        end loop;
-                else
-                        perform acs_permission__grant_permission(
-				p_item_id,		-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                        );
-                end if;
-		return 0;
-end;' language 'plpgsql';
-
-
-create	function static_page__revoke_permission (
-                integer,	-- item_id in acs_permissions.object_id%TYPE,
-                integer,	-- grantee_id	in acs_permissions.grantee_id%TYPE,
-                varchar,	-- privilege	in acs_permissions.privilege%TYPE,
-                boolean		-- recursive_p	in char
-        ) returns integer as '
-	declare
-                p_item_id	alias for $1;
-                p_grantee_id	alias for $2;
-                p_privilege	alias for $3;
-                p_recursive_p	alias for $4;
-		v_file_row	RECORD;
-		v_folder_row	RECORD;
-        begin
-                if p_recursive_p = ''t'' then
-                        -- For each folder that is a descendant of item_id, revoke.
-                        for v_folder_row in 
-                          select s1.folder_id from sp_folders s1, sp_folders s2
-                          where s2.folder_id = p_item_id
-                            and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                         loop
-                                perform acs_permission__revoke_permission(
-				v_folder_row.folder_id,	-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                                );
-                        end loop;
-                        -- For each file that is a descendant of item_id, revoke.
-                        for v_file_row in 
-                          select sp.static_page_id
-                          from static_pages sp, sp_folders s1, sp_folders s2
-                          where sp.folder_id = s1.folder_id
-                            and s2.folder_id = p_item_id
-                            and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
-                         loop
-                                perform acs_permission__revoke_permission(
-				v_file_row.static_page_id,	-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                                );
-                        end loop;
-                else
-                        perform acs_permission__revoke_permission(
-				p_item_id,		-- object_id 
-				p_grantee_id,		-- grantee_id
-				p_privilege		-- privilege 
-                        );
-                end if;
-		return 0;
-end;' language 'plpgsql';
-
-create	function static_page__five_n_spaces (
-                integer		-- n	in integer
-        ) returns varchar as '
-	declare
-		p_n	alias for $1;
-                space_string	varchar(400);
-        begin
-                space_string := '''';
-                for i in 1..p_n loop
-                        space_string := space_string || ''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'';
-                end loop;
-                return space_string;
-end;' language 'plpgsql';
-
-create	function static_page__set_show_comments_p (
-                integer,	-- item_id	in acs_permissions.object_id%TYPE,
-                boolean		-- show_comments_p	in static_pages.show_comments_p%TYPE
-        ) returns integer as '
-	declare
-		p_item_id		alias for $1;
-		p_show_comments_p 	alias for $2;
-        begin
-                update static_pages
-                set show_comments_p = p_show_comments_p
-                where static_page_id = p_item_id;
-		return 0;
-end;' language 'plpgsql';
-
-create	function static_page__get_show_comments_p (
-                integer		-- item_id in acs_permissions.object_id%TYPE
-        ) returns boolean as '
-	declare
-		p_item_id 	alias for $1;	-- p_ stands for parameter
-                v_show_comments_p	static_pages.show_comments_p%TYPE;
-        begin
-                select show_comments_p into v_show_comments_p from static_pages
-                where static_page_id = p_item_id;
-
-                return v_show_comments_p;
-end;' language 'plpgsql';
-
-
+\i static-page-pb.sql
 \i static-pages-sc-create.sql
--- end static_page;
-
-
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/postgresql/upgrade/upgrade-4.2a-4.3.sql'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: openacs-4/packages/static-pages/tcl/static-pages-init.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-init.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/tcl/static-pages-init.tcl	15 Dec 2001 01:39:01 -0000	1.2
+++ openacs-4/packages/static-pages/tcl/static-pages-init.tcl	16 Jan 2003 14:01:59 -0000	1.3
@@ -1,13 +1,40 @@
 # setup the STATIC_PAGES location for CR_LOCATIONS so that all paths
 # stored in the db are relative to the OpenACS installation dir
 
-if ![nsv_exists CR_LOCATIONS STATIC_PAGES] {
-    nsv_set CR_LOCATIONS STATIC_PAGES "[file dirname [string trimright [ns_info tcllib] "/"]]/www"
+if { ![nsv_exists CR_LOCATIONS STATIC_PAGES] } {
+    # Since we allow the fs_root of static-pages package instances to
+    # be beneath the packages/ directory, this must now be relative to
+    # the server root (e.g., "/web/mysite/"), not the web root (e.g.,
+    # "/web/mysite/www/"):  --atp@piskorski.com, 2002/12/12 16:17 EST
+
+    nsv_set CR_LOCATIONS STATIC_PAGES "[file dirname [string trimright [ns_info tcllib] "/"]]"
 }
 
-if ![nsv_exists static_pages package_id] {
-    nsv_set static_pages package_id [apm_package_id_from_key static-pages]
+
+# Use these to insure that only 1 copy of sp_sync_cr_with_filesystem
+# per Static Pages package instance ever runs at once.  For each
+# package_id in the array, empty string means not running, a string
+# means is curretnly running, and the string will give the time the
+# proc started running:
+
+set nsv {sp_sync_cr_fs_times}
+if { ![nsv_array exists $nsv] } {
+    nsv_array set $nsv [list]
+    #nsv_set $nsv foo bar ; nsv_unset $nsv foo
 }
 
+set key {sp_sync_cr_fs_mutex}
+if { ![nsv_exists . $key] } {
+    nsv_set . $key [ns_mutex create]
+}
+
+
+# Register the handler for each static page file extension.
+sp_register_extension
+
+
+# Once per night, at 4 am:
+#ad_schedule_proc -thread t -schedule_proc ns_schedule_daily [list 04 00] sp_sync_cr_with_filesystem_scheduled
+
+
 ns_log notice "static-pages-init.tcl loaded"
-    
\ No newline at end of file
Index: openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql,v
diff -u -r1.9 -r1.10
--- openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql	6 Sep 2002 12:02:27 -0000	1.9
+++ openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql	16 Jan 2003 14:01:59 -0000	1.10
@@ -3,7 +3,7 @@
 <queryset>
    <rdbms><type>oracle</type><version>8.1.6</version></rdbms>
 
-<fullquery name="sp_sync_cr_with_filesystem.create_new_folder">
+<fullquery name="sp_sync_cr_with_filesystem_internal.create_new_folder">
       <querytext>
 
 			    begin
@@ -19,7 +19,7 @@
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.update_db_file">
+<fullquery name="sp_sync_cr_with_filesystem_internal.update_db_file">
       <querytext>
 
 			update cr_revisions set content = empty_blob()
@@ -29,7 +29,7 @@
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.check_db_for_page">
+<fullquery name="sp_sync_cr_with_filesystem_internal.check_db_for_page">
       <querytext>
 
 		select static_page_id from static_pages
@@ -38,33 +38,30 @@
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.do_sp_new">
+<fullquery name="sp_sync_cr_with_filesystem_internal.do_sp_new">
       <querytext>
-
-		    begin
-			:1 := static_page.new(
-				  filename => :sp_filename,
-				  title => :page_title,
-				  folder_id => :parent_folder_id
-			      );
-		    end;
-
+begin
+:1 := static_page.new(
+  filename   => :sp_filename
+  ,title     => :page_title
+  ,folder_id => :parent_folder_id
+  ,mime_type => :mime_type
+);
+end;
       </querytext>
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.insert_file_contents">
+<fullquery name="sp_sync_cr_with_filesystem_internal.insert_file_contents">
       <querytext>
-
 		    update cr_revisions set content = empty_blob()
 		    where revision_id = content_item.get_live_revision(:static_page_id)
 		    returning content into :1
-
       </querytext>
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.delete_old_files">
+<fullquery name="sp_sync_cr_with_filesystem_internal.delete_old_files">
       <querytext>
 
 	begin
@@ -88,7 +85,7 @@
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.get_db_page">
+<fullquery name="sp_sync_cr_with_filesystem_internal.get_db_page">
       <querytext>
 
 		    select content as file_from_db from cr_revisions
@@ -98,7 +95,7 @@
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.get_folder_id">
+<fullquery name="sp_sync_cr_with_filesystem_internal.get_folder_id">
       <querytext>
 
         select nvl((select item_id from cr_items where name=:cumulative_path),0)
@@ -167,4 +164,35 @@
 </querytext>
 </fullquery>
 
+
+<fullquery name="sp_get_page_id.page_and_package_ids">
+<querytext>
+select sp.static_page_id, f.package_id
+from static_pages sp, sp_folders f
+where sp.filename = :filename
+and sp.folder_id = f.folder_id
+-- Only want pages from the Static Pages package.
+and f.package_id in (
+  select package_id  from apm_packages
+  where package_key = :package_key )
+-- If the same page is in more than one instance of
+-- Static Pages for some reason, we only want one of
+-- them, and we don't care which.
+-- Oracle
+and rownum <= 1
+-- PostgreSQL
+--limit 1
+</querytext>
+</fullquery>
+
+
+<fullquery name="sp_package_url.get_mount_point">
+<querytext>
+select site_node.url(min(node_id)) as url
+from site_nodes
+where object_id = :package_id
+</querytext>
+</fullquery>
+
+
 </queryset>
Index: openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql,v
diff -u -r1.17 -r1.18
--- openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql	6 Sep 2002 12:02:27 -0000	1.17
+++ openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql	16 Jan 2003 14:01:59 -0000	1.18
@@ -3,7 +3,7 @@
 <queryset>
    <rdbms><type>postgresql</type><version>7.1</version></rdbms>
 
-<fullquery name="sp_sync_cr_with_filesystem.get_db_page">
+<fullquery name="sp_sync_cr_with_filesystem_internal.get_db_page">
       <querytext>
 
 		    select content as file_from_db from cr_revisions
@@ -13,7 +13,7 @@
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.get_folder_id">
+<fullquery name="sp_sync_cr_with_filesystem_internal.get_folder_id">
       <querytext>
 
         select coalesce((select item_id from cr_items where name=:cumulative_path),0)
@@ -22,7 +22,7 @@
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.create_new_folder">
+<fullquery name="sp_sync_cr_with_filesystem_internal.create_new_folder">
       <querytext>
                 select static_page__new_folder (
 			NULL, 			-- folder_id	
@@ -39,15 +39,15 @@
 </fullquery>
 
  
-<fullquery name="sp_sync_cr_with_filesystem.update_db_file">      
+<fullquery name="sp_sync_cr_with_filesystem_internal.update_db_file">      
       <querytext>
 		update cr_revisions set content = :sp_filename
 		where revision_id = content_item__get_live_revisions(:static_page_id)
    
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.check_db_for_page">
+<fullquery name="sp_sync_cr_with_filesystem_internal.check_db_for_page">
       <querytext>
 
 		select static_page_id, mtime as mtime_from_db from static_pages
@@ -56,30 +56,26 @@
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.do_sp_new">      
+<fullquery name="sp_sync_cr_with_filesystem_internal.do_sp_new">      
       <querytext>
-                select static_page__new(
-                        :parent_folder_id,       -- folder_id
-                        :sp_filename,                  -- filename
-                        :page_title,            -- title
-			:mtime_from_fs			-- mtime
-
-                );
+select static_page__new(
+  :parent_folder_id,  -- folder_id
+  :sp_filename,       -- filename
+  :page_title,        -- title
+  :mtime_from_fs      -- mtime
+  ,:mime_type         -- mime_type
+);
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.insert_file_contents">
+<fullquery name="sp_sync_cr_with_filesystem_internal.insert_file_contents">
       <querytext>
-
 		update cr_revisions set content = :sp_filename
-		where revision_id = content_item__get_live_revisions(:static_page_id)
-
-
-      </querytext>
+		where revision_id = content_item__get_live_revisions(:static_page_id)      </querytext>
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.delete_old_files">
+<fullquery name="sp_sync_cr_with_filesystem_internal.delete_old_files">
       <querytext>
 	begin
 	perform static_page__delete_stale_items(:sync_session_id,:package_id);
@@ -159,4 +155,34 @@
 </fullquery>
 
 
+<fullquery name="sp_get_page_id.page_and_package_ids">
+<querytext>
+select sp.static_page_id, f.package_id
+from static_pages sp, sp_folders f
+where sp.filename = :filename
+and sp.folder_id = f.folder_id
+-- Only want pages from the Static Pages package.
+and f.package_id in (
+  select package_id  from apm_packages
+  where package_key = :package_key )
+-- If the same page is in more than one instance of
+-- Static Pages for some reason, we only want one of
+-- them, and we don't care which.
+-- Oracle
+--and rownum <= 1
+-- PostgreSQL
+limit 1
+</querytext>
+</fullquery>
+
+
+<fullquery name="sp_package_url.get_mount_point">
+<querytext>
+select site_node__url(min(node_id)) as url
+from site_nodes
+where object_id = :package_id
+</querytext>
+</fullquery>
+
+
 </queryset>
Index: openacs-4/packages/static-pages/tcl/static-pages-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs.tcl,v
diff -u -r1.11 -r1.12
--- openacs-4/packages/static-pages/tcl/static-pages-procs.tcl	6 Sep 2002 12:02:27 -0000	1.11
+++ openacs-4/packages/static-pages/tcl/static-pages-procs.tcl	16 Jan 2003 14:01:59 -0000	1.12
@@ -7,18 +7,96 @@
     @cvs-id $Id$
 }
 
-ad_proc -public sp_sync_cr_with_filesystem { 
+
+ad_proc -public sp_sync_cr_with_filesystem_scheduled {{}} {
+
+    Sync the filesystem and the content repository in a scheduled
+    procedure, rather than manually.  Calls sp_sync_cr_with_filesystem
+    just like the www/admin/fs-scan-progress.tcl page does.
+
+    <p>
+    Note that if you have comments turned on, be <em>very carefull</em>
+    running this, as the current implementation of
+    sp_sync_cr_with_filesystem will <em>destroy</em> any user
+    contributed comments on the file if you temporarily delete the
+    file, then run that procedure.
+
+    @author Andrew Piskorski (atp@piskorski.com)
+    @creation-date 2002/09/12
+} {
+    set proc_name {sp_sync_cr_with_filesystem_scheduled}
+    ns_log Notice "$proc_name: Starting."
+
+    # sp_sync_cr_with_filesystem callbacks to fill file_items with info:
+
+    proc sp_sch_old_item { path id } {}
+    proc sp_sch_new_item { path id } {}
+    proc sp_sch_changed_item { path id } {
+        # The title may have changed:
+        sp_flush_page $id
+    }
+
+    # TODO: We can have more than one package instance, so must decide
+    # here WHICH package instance to run the sync for.  This should
+    # probably be something configurable for each package instance from
+    # the admin page, but for now we simply find and sync ALL package
+    # instances: --atp@piskorski.com, 2002/09/12 14:02 EDT
+
+    set package_key [sp_package_key_is]
+
+    db_foreach each_apm_package_instance {
+        select  package_id, instance_name
+        from apm_packages
+        where package_key = :package_key
+        order by package_id
+    } {
+        set root_folder_id [sp_root_folder_id $package_id]
+        set fs_root "[acs_root_dir][ad_parameter -package_id $package_id {fs_root}]"
+
+        ns_log Notice "$proc_name: About to scan the filesystem for:  package_id '$package_id', instance_name '$instance_name', fs_root '$fs_root':"
+
+        # If our call to sp_sync_cr_with_filesystem fails for some
+        # reason, want to continue on trying the other package
+        # instances:
+
+        set sync_proc {sp_sync_cr_with_filesystem}
+        if { [catch {
+            set result [$sync_proc  -package_id $package_id \
+                            -file_unchanged_proc    sp_sch_old_item \
+                            -file_add_proc          sp_sch_new_item \
+                            -file_change_proc       sp_sch_changed_item \
+                            -folder_add_proc        sp_sch_new_item \
+                            -folder_unchanged_proc  sp_sch_old_item \
+                            $fs_root $root_folder_id]
+        } errmsg] } {
+            global errorInfo
+            ns_log Error "$proc_name: For package_id: '$package_id', $sync_proc failed with error:\n${errorInfo}"
+        } else {
+            ns_log Notice "$proc_name: For package_id: '$package_id': $result"
+        }
+
+    } if_no_rows {
+        ns_log Warning "$proc_name: NO package ids found for package key: '$package_key'."
+    }
+
+    ns_log Notice "$proc_name: Done."
+}
+
+
+ad_proc -public sp_sync_cr_with_filesystem {
     {
-	-file_add_proc ""
-	-file_change_proc ""
-	-file_unchanged_proc ""
-	-folder_add_proc ""
-	-folder_unchanged_proc ""
+        -file_add_proc ""
+        -file_change_proc ""
+        -file_unchanged_proc ""
+        -file_read_error_proc ""
+        -folder_add_proc ""
+        -folder_unchanged_proc ""
+        -package_id ""
     }
     fs_root
     root_folder_id
     {
- 	static_page_regexp {}	
+       static_page_regexp {}
     }
 } {
     Synchronize the content repository with the file system.
@@ -42,7 +120,7 @@
     @param folder_unchanged_proc The name of a Tcl proc to be called for each folder
                                  unchanged in the database.
 
-    @param fs_root The starting path in the filesystem. This is relative to the openacs install directory,  Files below this point will 
+    @param fs_root The starting path in the filesystem.  Files below this point will 
                    be scanned.
 
     @param root_folder_id The id of the root folder in the static-pages system (and in 
@@ -51,16 +129,185 @@
 
     @param static_page_regexp A regexp to identify static pages.
 
-    @author Brandoch Calef (bcalef@arsdigita.com)
-    @creation-date 2001-02-07
+    @param package_id Optionally, the package id of the Static Pages
+    instance.  If not specified, determined from ad_conn.
+
+    @author Andrew Piskorski (atp@piskorski.com)
+    @creation-date 2001/08/27
 } {
+   if { [empty_string_p $package_id] } {
+      set package_id [ad_conn package_id]
+   }
+
+   if { [catch { set return_val [sp_sync_cr_with_filesystem_internal \
+           -file_add_proc          $file_add_proc         \
+           -file_change_proc       $file_change_proc      \
+           -file_unchanged_proc    $file_unchanged_proc   \
+           -file_read_error_proc   $file_read_error_proc  \
+           -folder_add_proc        $folder_add_proc       \
+           -folder_unchanged_proc  $folder_unchanged_proc \
+           -package_id             $package_id            \
+           -stack_depth  2 \
+           {return_mesg}  $fs_root  $root_folder_id  $static_page_regexp ]
+   } result] } {
+      # We caught an unexpected error, so clean up the mutex, and then
+      # re-throw the exact same error:
+
+      sp_sync_cr_with_filesystem_unlock $package_id
+
+      global errorInfo
+      error $result $errorInfo
+   } else {
+      return $return_mesg
+   }
+}
+
+
+ad_proc -private sp_sync_cr_with_filesystem_unlock {package_id} {
+   Unlocks the sp_sync_cr_with_filesystem_times variable - use upon
+   abnormal termination of the sp_sync_cr_with_filesystem_internal
+   stuff.  We have it as a separate proc here to make it convenient to
+   call from within multiple different procedures.
+
+   @author Andrew Piskorski (atp@piskorski.com)
+   @creation-date 2001/08/27
+} {
+    set mutex [nsv_get . {sp_sync_cr_fs_mutex}]
+    ns_mutex lock $mutex
+    nsv_set {sp_sync_cr_fs_times} $package_id {}
+    ns_mutex unlock $mutex
+}
+
+
+ad_proc -private sp_sync_cr_with_filesystem_internal { 
+    {
+        -file_add_proc ""
+        -file_change_proc ""
+        -file_unchanged_proc ""
+        -file_read_error_proc ""
+        -folder_add_proc ""
+        -folder_unchanged_proc ""
+        -package_id ""
+        -stack_depth 1
+    }
+    return_mesg_var
+    fs_root
+    root_folder_id
+    {
+       static_page_regexp {}
+    }
+} {
+   This procedure was originally named sp_sync_cr_with_filesystem
+   procedure, but has been renamed and modified so that it can be
+   wrapped inside the new sp_sync_cr_with_filesystem, to support the
+   mutex locking.
+   <p>
+   We wrap it because at the end of this proc, we must set
+   sp_sync_cr_with_filesystem_times($package_id) back to empty string.
+   But if we hit some random untrapped error partway through, we'll
+   never get there.  Therefore, we wrap this proc inside another, and
+   have the wrapper proc catch any errors thrown by this proc, set the
+   var back to empty string, then re-throw the error.
+   <p>
+   This procedure takes the exact same arguments as its
+   sp_sync_cr_with_filesystem wrapper proc, except for the addition of
+   return_mesg_var.
+   <p>
+   You should <em>never</em> call this procedure, except from
+   sp_sync_cr_with_filesystem.
+
+   @param return_mesg_var Name of variable in which to return text
+   message, for presentation on a web page to the user.
+
+   @param package_id <em>Must</em> be passed in, for this internal
+   version of the proc.
+
+   @author Brandoch Calef (bcalef@arsdigita.com)
+   @author Andrew Piskorski (atp@piskorski.com)
+   @creation-date 2001-02-07
+} {
+    set proc_name {sp_sync_cr_with_filesystem_internal}
+
+    if { [empty_string_p $package_id] } {
+        error "package_id '$package_id' is not valid."
+    }
+    upvar $return_mesg_var return_mesg
+    set return_mesg {}
+
+
+    # Make sure that only 1 copy of this proc per package instance
+    # ever runs at once:
+
+    set mutex [nsv_get . {sp_sync_cr_fs_mutex}]
+    set nsv {sp_sync_cr_fs_times}
+
+    # These multiple nsv operations need to all be atomic, so use a
+    # mutex:
+
+    ns_mutex lock $mutex
+
+    if { ![nsv_array exists $nsv] } {
+        ns_mutex unlock $mutex
+        error "nsv array '$nsv' does not exist!"
+    } elseif { ![nsv_exists $nsv $package_id] } {
+        # The package_id isn't in the array yet at all, so another copy
+        # is not running.
+        set other_start_time {}
+    } else {
+        set other_start_time [nsv_get sp_sync_cr_fs_times $package_id]
+    }
+
+    if { [empty_string_p $other_start_time] } {
+        # We're ok, no other copy is running.
+        nsv_set $nsv $package_id [ns_time]
+        set run_p 1
+    } else {
+        set run_p 0
+    }
+
+    ns_mutex unlock $mutex
+    ns_log Notice "atp: $proc_name: other_start_time: '$other_start_time'"
+
+    if { ! $run_p } {
+        # Another copy is running, must abort:
+        set time_diff [expr [ns_time] -  $other_start_time]
+
+        set other_time_pretty [ns_httptime $other_start_time]
+        # Could also use: [clock format [clock seconds]]
+
+        set mesg "sp_sync_cr_with_filesystem: Already running. sp_sync_cr_fs_times($package_id) == $other_time_pretty, $time_diff seconds ago."
+        ns_log Warning $mesg
+
+        set return_mesg "Another copy of this procedure is already running for
+       this package instance.  It started running $time_diff seconds
+       ago, at $other_time_pretty.  Only one copy may run at a time.
+       Please wait and then try again."
+
+        # Whether you actually see this happen depends whether the
+        # second thread running this proc gets scheduled or not before
+        # the first one completes.  If your machine is slow enough, or
+        # you have enough threads going at once, you will see it.
+        # --atp@piskorski.com, 2002/12/16 03:57 EST
+
+        return 0
+    }
+
+
     set sync_session_id [db_nextval sp_session_id_seq]
 
     set fs_trimmed [string trimright $fs_root "/"]
     set fs_trimmed_length [string length $fs_trimmed]
 
-    set static_page_regexp "\\.[join [split [string trim [ad_parameter -package_id [nsv_get static_pages package_id] AllowedExtensions]] " "] "$|\\."]$"
+    set static_page_regexp "\\.[join [split [string trim [ad_parameter -package_id $package_id AllowedExtensions]] " "] "$|\\."]$"
 
+    # TODO: What happens if at some point, an Admin CHANGES the
+    # fs_root parameter for a Static Pages package instance?  BAD
+    # THINGS, I suspect.  We're probably invisibly orphaning content
+    # inside the Content Repository.  Look into this.  For now, simply
+    # DO NOT change the fs_root of an already in use Static Pages
+    # package instance.
+    # --atp@piskorski.com, 2002/09/15 10:03 EDT
+
     foreach file [ad_find_all_files $fs_root] {
 	if { [regexp -nocase $static_page_regexp $file match] } {
 	    # Chop the starting path off of the full pathname and split it up:
@@ -82,18 +329,19 @@
 		    if { $folder_id == 0} {
 			set folder_id [db_exec_plsql create_new_folder {}]
 			if { [string length $folder_add_proc] > 0 } {
-			    uplevel "$folder_add_proc $cumulative_path $folder_id"
+			    uplevel $stack_depth "$folder_add_proc $cumulative_path $folder_id"
 			}
 		    } else {
 			if { [string length $folder_unchanged_proc] > 0 } {
-			    uplevel "$folder_unchanged_proc $cumulative_path $folder_id"
+			    uplevel $stack_depth "$folder_unchanged_proc $cumulative_path $folder_id"
 			}
 		    }
 		    set path_exists($cumulative_path) $folder_id
 		    db_dml insert_path {
 			insert into sp_extant_folders (session_id,folder_id)
 			values (:sync_session_id,:folder_id)
 		    }
+
 		} else {
 		    set folder_id $path_exists($cumulative_path)
 		}
@@ -111,17 +359,30 @@
 	    # install dir, this is what gets inserted into the db - DaveB
 	    set sp_filename [sp_get_relative_file_path $file]
 	    set mtime_from_fs [file mtime $file]
+
    	    if [db_0or1row check_db_for_page {
 		select static_page_id, mtime as mtime_from_db from static_pages
 		where filename = :sp_filename
 	    }] {
+
 	       if { [catch {
 		    set fp [open $file r]
 		    set file_from_fs [read $fp]
 		    close $fp
 		} errmsg]} {
-		    ad_return_error "Error reading file" \
-			    "This error was encountered while reading $file: $errmsg"
+                    # Log and return an appropriate message, then
+                    # continue on trying to process the other files.
+                    # We do NOT want to abort the whole scan just
+                    # because one file had problems:
+                    # --atp@piskorski.com, 2002/09/12 16:49 EDT
+
+                    set mesg "$proc_name: Error reading file: '$file':  [ns_quotehtml $errmsg]"
+                    ns_log Error $mesg
+                    if { ![empty_string_p $file_read_error_proc] } {
+                        ns_log Notice "$proc_name: about to run file_read_error_proc:"
+                        uplevel $stack_depth [list $file_read_error_proc $file $static_page_id $mesg]
+                    }
+                    continue
 		}
 	    
 		set file_updated 0
@@ -160,28 +421,42 @@
 			}
 		    }
 			if { [string length $file_change_proc] > 0 } {
-			    uplevel "$file_change_proc $file $static_page_id"
+			    uplevel $stack_depth "$file_change_proc $file $static_page_id"
 			}
 		} else {
 		    if { [string length $file_unchanged_proc] > 0 } {
-			uplevel "$file_unchanged_proc $file $static_page_id"
+			uplevel $stack_depth "$file_unchanged_proc $file $static_page_id"
 		    }
 		}
 		db_dml insert_file {
 		    insert into sp_extant_files (session_id,static_page_id)
 		    values (:sync_session_id,:static_page_id)
 		}
 	    } else {
+                # The file is NOT in the db yet at all:
+
 		# Try to extract a title:
 		if { [catch {
 		    set fp [open $file r]
 		    set file_contents [read $fp]
 		    close $fp
 		} errmsg]} {
-		    ad_return_error "Error reading file" \
-			    "This error was encountered while reading $file: $errmsg"
+                    # Log and return an appropriate message, then
+                    # continue on trying to process the other files.
+                    # We do NOT want to abort the whole scan just
+                    # because one file had problems:
+                    # --atp@piskorski.com, 2002/09/12 16:49 EDT
+
+                    set mesg "$proc_name: Error reading file: '$file':  [ns_quotehtml $errmsg]"
+                    ns_log Error $mesg
+                    if { ![empty_string_p $file_read_error_proc] } {
+                        ns_log Notice "$proc_name: about to run file_read_error_proc:"
+                        uplevel $stack_depth [list $file_read_error_proc $file $static_page_id $mesg]
+                    }
+                    continue
 		}
 
+                # TODO:  This is very HTML specific:  --atp@piskorski.com, 2001/08/13 21:58 EDT
 		if { ![regexp -nocase {<title.*?>(.+?)</title} $file_contents match page_title] } {
 		    regexp {[^/]*$} $file page_title
 		}
@@ -193,23 +468,20 @@
 		# seperately.  This is simple (get item_id from static_page.new(),
 		# then update cr_revisions to insert the blob) but involved direct
 		# manipulation of the cr_revisions table.
-		set static_page_id [db_exec_plsql do_sp_new {
-		    begin
-			:1 := static_page.new(
-				  filename => :sp_filename,
-				  title => :page_title,
-				  folder_id => :parent_folder_id
-			      );
-		    end;
-		}]
+
+                # If you run two copies of sp_sync_cr_with_filesystem
+                # at once, you CAN get "ORA-00001: unique constraint
+                # (CR_ITEMS_UNIQUE_NAME) violated" errors here when
+                # calling static_page.new - thus the addition of mutex
+                # locking.  --atp@piskorski.com, 2001/08/27 01:20 EDT
+
+                set mime_type [sp_maybe_create_new_mime_type $sp_filename]
+		set static_page_id [db_exec_plsql do_sp_new {}]
 		# Check if -blobs [list $file_contents] would be faster:
-		db_dml insert_file_contents {
-		    update cr_revisions set content = empty_blob()
-		    where revision_id = content_item.get_live_revision(:static_page_id)
-		    returning content into :1
-		} -blob_files [list $file]
+		db_dml insert_file_contents {} -blob_files [list $file]
+
 		if { [string length $file_add_proc] > 0 } {
-		    uplevel "$file_add_proc $file $static_page_id"
+		    uplevel $stack_depth "$file_add_proc $file $static_page_id"
 		}
 		db_dml insert_file {
 		    insert into sp_extant_files (session_id,static_page_id)
@@ -219,8 +491,22 @@
 	}
     }
 
+    # TODO: This is very wrong.  Should NEVER just delete all content! 
+    # Note that the canonical content of the file itself lives in the 
+    # fileystem and can easily be re-imported to the database, but 
+    # this ALSO blindly deletes all user-contributed comments which 
+    # point to the file! 
+    # 
+    # See also: http://openacs.org/bboard/q-and-a-fetch-msg.tcl?msg_id=0002U2 
+    # 
+    # --atp@piskorski.com, 2001/08/13 15:07 EDT 
+ 
     # Clean up any files that are in the db but no longer in the filesystem:
-    set package_id [ad_conn package_id]
+
+    # TODO: Why are we doing these two deletes after calling
+    # static_page.delete_stale_items?
+    # --atp@piskorski.com, 2001/08/23 02:20 EDT 
+
     db_exec_plsql delete_old_files {
 	begin
 	    static_page.delete_stale_items(:sync_session_id,:package_id);
@@ -229,8 +515,18 @@
 	    delete from sp_extant_files where session_id = :sync_session_id;
 	end;
     }
+
+    # TODO: We should have a sp_deleted_item hook just like we do for
+    # new, old, and changd items.  As it is now, we delete the file
+    # out of the database but provide NO notification that we did so.
+    # --atp@piskorski.com, 2002/12/12 12:43 EST
+
+    sp_sync_cr_with_filesystem_unlock $package_id
+    set return_mesg "Done."
+    return 0
 }
 
+
 ad_proc -public sp_root_folder_id { package_id } {
     Returns the id of the root folder associated with package_id,
     creating one if necessary.
@@ -357,14 +653,24 @@
 
 
 ad_proc -private sp_get_page_id { filename } {
-    Gets page_id
+    Returns a two item list of the page_id and the static-pages
+    package_id it belongs to.
+
     @author Dave Bauer (dave@thedesignexperience.org)
     @creation-date 2001-07-30
 } {
-    return [list [db_string search_page "
-    select static_page_id from static_pages sp, sp_folders spf 
-               where filename='$filename' and sp.folder_id=spf.folder_id
-               and package_id=[apm_package_id_from_key "static-pages"]" -default -1]]
+    # This package is no longer a singleton, so can't use
+    # apm_package_id_from_key here: --atp@piskorski.com, 2001/08/26
+    # 22:37 EDT
+
+    set package_key [sp_package_key_is]
+    if { [db_0or1row page_and_package_ids {}] } {
+        set results [list $static_page_id $package_id]
+    } else {
+        set results [list -1 -1]
+    }
+
+    return $results
 }
 
 ad_proc -public sp_flush_page { page_id } {
@@ -377,6 +683,116 @@
     util_memoize_flush [list sp_get_page_info_query $page_id]
 }
 
+
+ad_proc sp_maybe_create_new_mime_type {
+    file_name
+} {
+    This proc should be identical to fs_maybe_create_new_mime_type
+    from the file-storage package.  However, we don't want to depend
+    on file-storage being loaded, so if it isn't, define our own
+    implementation here.  --atp@piskorski.com, 2002/12/15 19:34 EST
+
+    <p>
+    The content repository expects the MIME type to already be defined
+    when you upload content.  We use this procedure to add a new type
+    when we encounter something we haven't seen before.
+
+    @author Andrew Piskorski (atp@piskorski.com)
+    @creation-date 2002-12-15
+} {
+    set func {fs_maybe_create_new_mime_type}
+
+    if { [nsv_exists api_proc_doc $func] ||
+         ![empty_string_p [namespace eval :: [list info procs $func]]]
+     } {
+        # The file-storage version of this proc exists, use it:
+        return [list $func $file_name]
+
+    } else {
+        # Fall back to local implementation:
+
+        set file_extension [string trimleft [file extension $file_name] "."]
+        if {[empty_string_p $file_extension]} {
+            return "*/*"
+        }
+
+        # TODO: This insert may fail due to a race condition.  Should be
+        # locking the cr_mime_types table first:
+        # --atp@piskorski.com, 2001/08/23 20:20 EDT
+
+        if {![db_0or1row select_mime_type {
+            select mime_type
+            from cr_mime_types
+            where file_extension = :file_extension
+        }]} {
+            # A mime type for this file extension does not exist
+            # in the database.  Check to see AOLServer can 
+            # generate a mime type.
+
+            set mime_type [ns_guesstype $file_name]
+            
+            # Note: If AOLServer can't determine a mime type, 
+            # ns_guesstype will return */*. We still record
+            # a mime type for this file extension.  At a later
+            # date, the mime type for the file extension may be
+            # updated and, as a result, the files with that
+            # file extension will be associated with the
+            # proper mime types.
+
+            db_dml new_mime_type {
+                insert into cr_mime_types
+                (mime_type, file_extension)
+                values
+                (:mime_type, :file_extension)
+            }
+        }
+        return $mime_type
+    }
+}
+
+
+ad_proc -public sp_package_key_is {} {
+   Simply returns the package key string for this package.
+   @author Andrew Piskorski (atp@piskorski.com)
+   @creation-date 2001/08/26
+} {
+   # TODO: Might want to have this pull and cache the actual key from
+   # the database.
+   return {static-pages}
+}
+
+
+ad_proc -private sp_package_url {package_key} {
+   <p>Given a package key, return a URL of a mounted
+   package instance. If there is more than one instance
+   of the package mounted, the one with the lowest
+   <code>package_id</code> will be returned. If the
+   package is not instantiated or not mounted anywhere,
+   an error is raised. The proc is meant to be memoized.
+   </p>
+} {
+    set proc_name {sp_package_url}
+
+    set found_p [db_0or1row get_any_package_instance {
+        select min(package_id) as package_id
+        from apm_packages
+        where package_key = :package_key
+    }]
+
+    if { !$found_p } {
+        error "$proc_name: the '$package_key' package is not instantiated."
+    }
+
+    set found_p [db_0or1row get_mount_point {}]
+
+    if { !$found_p } {
+        error "$proc_name: the '$package_key' package is not mounted."
+    }
+
+    return $url
+}
+
+
 ad_proc -public sp_serve_html_page { } {
     Registered proc to serve up static pages.
 
@@ -385,18 +801,26 @@
 } {
     set filename [ad_conn file]
     set sp_filename [sp_get_relative_file_path $filename]
-     
-    set page_id [util_memoize [list sp_get_page_id $sp_filename]]
 
-    set package_id [nsv_get static_pages package_id]
+    # In order to determine per-instance parameters like
+    # TemplatingEnabledP, need to know the package_id of the
+    # static-pages instance where this page is located, which is
+    # likely NOT the package_id returned by [ad_conn package_id]:
 
+    foreach [list page_id package_id] \
+        [util_memoize [list sp_get_page_id $sp_filename]] { break }
+
     set file [ad_conn file]
     ad_conn -set subsite_id [site_node_closest_ancestor_package "acs-subsite"]
 
     # If the page is in the db, serve it carefully; otherwise just dump it out.
     if { $page_id >= 0 } {
         set page_info [util_memoize [list sp_get_page_info_query $page_id]]
 
+        # TODO: Below, what if we only allow registered users to make
+        # comments?  Or some smaller group of users?  What then?
+        # --atp@piskorski.com, 2001/08/22 23:09 EDT
+
         # We only show the link here if the_public has 
         # general_comments_create privilege on the page.  Why the_public
         # rather than the current user?  Because we don't want admins to
@@ -431,7 +855,8 @@
         set body [template::util::read_file $file]
     }
 
-    if { [ad_parameter -package_id $package_id TemplatingEnabledP] } {
+    set templating_enabled [ad_parameter -package_id $package_id TemplatingEnabledP]
+    if { ![empty_string_p $templating_enabled] && $templating_enabled } {
 	# Strip out the <body>..</body> part as page will now be part of a master template
 	set headers ""
 	set sp_scripts ""
@@ -454,13 +879,47 @@
     }
 }
 
+
 ad_proc -private sp_register_extension {} {
     Register the handler for each static page file extension.
 } {
-    foreach extension [split [string tolower [string trim [ad_parameter -package_id [apm_package_id_from_key static-pages] AllowedExtensions]]] " "] {
-	rp_register_extension_handler $extension sp_serve_html_page
-	rp_register_extension_handler [string toupper $extension] sp_serve_html_page
+    set proc_name {sp_register_extension}
+
+    set package_key [sp_package_key_is]
+    set package_ids [db_list all_static_pages_package_instances {
+        select package_id
+        from apm_packages
+        where package_key = :package_key
+    }]
+
+    # Generate unique list of all file-name extensions used by all
+    # package instances:
+
+    array set extensions_arr [list]
+    foreach package_id $package_ids {
+        foreach extension [split [string tolower [string trim [ad_parameter -package_id $package_id AllowedExtensions]]] " "] {
+            set extensions_arr($extension) {}
+        }
     }
+
+    foreach extension [array names extensions_arr] {
+        # TODO: Are we supposed to use the sp_serve_html_page proc for
+        # ALL file-name extensions, even if they're PDF or MS Word
+        # documents?  I think not!  Need a better way to map file-name
+        # extensions to proper static-pages extension handler procs.
+        # --atp@piskorski.com, 2002/12/11 22:55 EST
+
+        if { [regexp {htm} $extension] } {
+            set handler_proc {sp_serve_html_page}
+            rp_register_extension_handler $extension $handler_proc
+            rp_register_extension_handler [string toupper $extension] $handler_proc
+        } else {
+            ns_log Notice "$proc_name:  NOT registering any proc to handle files with extension '$extension'."
+
+            # TODO: Add a PDF or other extension handler?  Necessary
+            # only if you want to be able to make comments on non-HTML
+            # files, I think.
+            # --atp@piskorski.com, 2002/12/11 22:55 EST
+        }
+    }
 }
-# Register the handler for each static page file extension.
-sp_register_extension
Index: openacs-4/packages/static-pages/tcl/static-pages-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs.xql,v
diff -u -r1.7 -r1.8
--- openacs-4/packages/static-pages/tcl/static-pages-procs.xql	3 Dec 2001 16:58:46 -0000	1.7
+++ openacs-4/packages/static-pages/tcl/static-pages-procs.xql	16 Jan 2003 14:01:59 -0000	1.8
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <queryset>
 
-<fullquery name="sp_sync_cr_with_filesystem.insert_path">
+<fullquery name="sp_sync_cr_with_filesystem_internal.insert_path">
       <querytext>
 
 			insert into sp_extant_folders (session_id,folder_id)
@@ -10,15 +10,15 @@
       </querytext>
 </fullquery>
 
-<fullquery name="sp_sync_cr_with_filesystem.get_storage_type">
+<fullquery name="sp_sync_cr_with_filesystem_internal.get_storage_type">
 	<querytext>
 		select storage_type from cr_items
 			where item_id = :static_page_id
 	</querytext>
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.insert_file">
+<fullquery name="sp_sync_cr_with_filesystem_internal.insert_file">
       <querytext>
 
 		    insert into sp_extant_files (session_id,static_page_id)
@@ -28,7 +28,7 @@
 </fullquery>
 
 
-<fullquery name="sp_sync_cr_with_filesystem.insert_file">
+<fullquery name="sp_sync_cr_with_filesystem_internal.insert_file">
       <querytext>
 
 		    insert into sp_extant_files (session_id,static_page_id)
Index: openacs-4/packages/static-pages/www/page-visit.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/page-visit.tcl,v
diff -u -r1.4 -r1.5
--- openacs-4/packages/static-pages/www/page-visit.tcl	18 Sep 2002 12:03:33 -0000	1.4
+++ openacs-4/packages/static-pages/www/page-visit.tcl	16 Jan 2003 14:02:32 -0000	1.5
@@ -19,11 +19,27 @@
 # characters will then be stripped off to produce the URL.
 # DaveB: not anymore! We chop off that part and just stuff the relative
 # path in the database to allow leaving the static-pages in the filesystem
-#
-#if { [string first "[acs_root_dir]/www" $filename] != 0 } {
-#    ad_return_error "Error in filename" "This page has an invalid filename."
-#}
 
 
-ad_returnredirect $filename
+# There are two possiblities: Either the static page is beneath the
+# site global www/ directory (and the filename starts "/www/"), or it
+# is beneath one of the package www directories (and the filename
+# starts "/packages/":
 
+if { [string first "/www/" $filename] == 0 } {
+    set redirect_to "/[string range $filename [string length "/www/"] end]"
+} elseif { [regexp "^/packages/(\[^/\]+)" $filename match package_dir] } {
+    # TODO: We are assuming that the package directory name $package_dir
+    # is in fact always the package key.  Is this really true?
+
+    if { ![regexp "^/packages/$package_dir/www/(.+)" $filename match url_part] } {
+        ad_return_error "Error in filename" "This page has an invalid filename: '$filename'."
+    }
+    set redirect_to "[sp_package_url $package_dir]$url_part"
+
+} else {
+    ad_return_error "Error in filename" "This page has an invalid filename: '$filename'."
+    return
+}
+
+ad_returnredirect $redirect_to
Index: openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl	6 Sep 2002 12:30:13 -0000	1.2
+++ openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl	16 Jan 2003 14:03:04 -0000	1.3
@@ -18,20 +18,23 @@
 # sp_sync_cr_with_filesystem callbacks to fill file_items with info.
 #
 proc sp_old_item { path id } {
-    upvar file_items file_items
-    ns_write "<br><code>$path</code>: <i>unchanged</i>"
+    ns_write "\n<br><code>$path</code>: <i>unchanged</i>"
 }
 proc sp_new_item { path id } {
-    upvar file_items file_items
-    ns_write "<br><code>$path</code>: <i>added</i>"
+    ns_write "\n<br><code>$path</code>: <i>added</i>"
 }
 proc sp_changed_item { path id } {
-    upvar file_items file_items
-    ns_write "<br><code>$path</code>: <i>updated</i>"
+    ns_write "\n<br><code>$path</code>: <i>updated</i>"
     # The title may have changed:
     sp_flush_page $id
 }
 
+proc sp_error_item { path id msg } {
+   ns_write "\n<br>
+<br><code>$path</code>: <strong>Error:</strong>
+<blockquote>$msg</blockquote>"
+}
+
 set title "Filesystem search"
 set context_bar [ad_context_bar $title]
 
@@ -41,18 +44,23 @@
 <h2>$title</h2>
 $context_bar
 <hr>
-Starting scan<br /><br />
 "
 
-set root_folder_id [sp_root_folder_id [ad_conn package_id]]
+set package_id [ad_conn package_id]
+set root_folder_id [sp_root_folder_id $package_id]
+set fs_root "[acs_root_dir][ad_parameter -package_id $package_id {fs_root}]"
 
-sp_sync_cr_with_filesystem \
+ns_write "
+<p>
+[sp_sync_cr_with_filesystem \
 	-file_unchanged_proc sp_old_item \
 	-file_add_proc sp_new_item \
 	-file_change_proc sp_changed_item \
+        -file_read_error_proc sp_error_item \
 	-folder_add_proc sp_new_item \
 	-folder_unchanged_proc sp_old_item \
-	"[acs_root_dir]/www" $root_folder_id
+	$fs_root $root_folder_id]
+<p>
+"
 
-
-ns_write "<p><strong>Finished updating static pages</strong></body></html>\n"
+ns_write "</body></html>\n"
Index: openacs-4/packages/static-pages/www/admin/fs-scan.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/fs-scan.adp,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/static-pages/www/admin/fs-scan.adp	6 Sep 2002 21:51:05 -0000	1.3
+++ openacs-4/packages/static-pages/www/admin/fs-scan.adp	16 Jan 2003 14:03:04 -0000	1.4
@@ -4,6 +4,11 @@
 
 <ul>
 <multiple name=file_items>
-  <li><code>@file_items.path@</code>: <i>@file_items.status@</i></li>
+  <li><code>@file_items.path@</code>: <i>@file_items.status@</i> @file_items.status_msg@</li>
 </multiple>
 </ul>
+
+<p>
+@result@
+
+<p>
Index: openacs-4/packages/static-pages/www/admin/fs-scan.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/fs-scan.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/www/admin/fs-scan.tcl	6 Sep 2002 12:30:13 -0000	1.2
+++ openacs-4/packages/static-pages/www/admin/fs-scan.tcl	16 Jan 2003 14:03:04 -0000	1.3
@@ -16,32 +16,41 @@
 #
 proc sp_old_item { path id } {
     upvar file_items file_items
-    multirow append file_items $path "unchanged"
+    multirow append file_items $path "unchanged" {}
 }
 proc sp_new_item { path id } {
     upvar file_items file_items
-    multirow append file_items $path "added"
+    multirow append file_items $path "added" {}
 }
 proc sp_changed_item { path id } {
     upvar file_items file_items
-    multirow append file_items $path "updated"
+    multirow append file_items $path "updated" {}
     # The title may have changed:
     sp_flush_page $id
 }
 
-multirow create file_items path status
+proc sp_error_item { path id msg } {
+    upvar file_items file_items
+    multirow append file_items $path {<strong>Error:</strong>} \
+        "<blockquote>$msg</blockquote>"
+}
 
+multirow create file_items path status status_msg
+
 set title "Filesystem search"
 set context [list $title]
 
-set root_folder_id [sp_root_folder_id [ad_conn package_id]]
+set package_id [ad_conn package_id]
+set root_folder_id [sp_root_folder_id $package_id]
+set fs_root "[acs_root_dir][ad_parameter -package_id $package_id {fs_root}]"
 
-sp_sync_cr_with_filesystem \
+set result [sp_sync_cr_with_filesystem \
 	-file_unchanged_proc sp_old_item \
 	-file_add_proc sp_new_item \
 	-file_change_proc sp_changed_item \
+        -file_read_error_proc sp_error_item \
 	-folder_add_proc sp_new_item \
 	-folder_unchanged_proc sp_old_item \
-	"[acs_root_dir]/www" $root_folder_id
+	$fs_root $root_folder_id]
 
 ad_return_template
Index: openacs-4/packages/static-pages/www/admin/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/index.adp,v
diff -u -r1.4 -r1.5
--- openacs-4/packages/static-pages/www/admin/index.adp	30 Nov 2002 17:49:14 -0000	1.4
+++ openacs-4/packages/static-pages/www/admin/index.adp	16 Jan 2003 14:03:04 -0000	1.5
@@ -2,7 +2,8 @@
 <property name="title">@title@</property>
 <property name="context">@context@</property>
 
-<p>There @are@ @n_static_pages@ static @pages@ in the system.</p>
+<p>There @are@ @n_static_pages@ static @pages@ in the 
+tree rooted at <code>@fs_root@</code>.</p>
 
 <p>
 <a href="fs-scan-progress">Scan filesystem for static pages</a>
Index: openacs-4/packages/static-pages/www/admin/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/index.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/www/admin/index.tcl	6 Sep 2002 12:30:13 -0000	1.2
+++ openacs-4/packages/static-pages/www/admin/index.tcl	16 Jan 2003 14:03:04 -0000	1.3
@@ -34,5 +34,5 @@
 }
 
 set title "Static Pages Administration"
-
+set fs_root "[acs_root_dir][ad_parameter {fs_root}]"
 set context [list $title]
Index: openacs-4/packages/survey/survey.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/survey.info,v
diff -u -r1.6 -r1.7
--- openacs-4/packages/survey/survey.info	2 Nov 2002 02:19:53 -0000	1.6
+++ openacs-4/packages/survey/survey.info	16 Jan 2003 14:03:37 -0000	1.7
@@ -72,8 +72,6 @@
             <file type="content_page" path="www/admin/question-add.tcl"/>
             <file type="content_page" path="www/admin/question-copy.tcl"/>
             <file type="query_file" path="www/admin/question-copy.xql"/>
-            <file type="content_page" path="www/admin/question-delete-2.tcl"/>
-            <file type="query_file" path="www/admin/question-delete-2.xql"/>
             <file type="query_file" db_type="oracle" path="www/admin/question-delete-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="www/admin/question-delete-postgresql.xql"/>
             <file type="content_page" path="www/admin/question-delete.adp"/>
@@ -184,6 +182,18 @@
             <file type="query_file" db_type="postgresql" path="www/response-postgresql.xql"/>
             <file type="content_page" path="www/view-attachment.tcl"/>
             <file type="query_file" path="www/view-attachment.xql"/>
+            <file type="content_page" path="www/graphics/add.gif"/>
+            <file type="content_page" path="www/graphics/admin.gif"/>
+            <file type="content_page" path="www/graphics/answer.gif"/>
+            <file type="content_page" path="www/graphics/copy.gif"/>
+            <file type="content_page" path="www/graphics/delete.gif"/>
+            <file type="content_page" path="www/graphics/down.gif"/>
+            <file type="content_page" path="www/graphics/edit.gif"/>
+            <file type="content_page" path="www/graphics/new.gif"/>
+            <file type="content_page" path="www/graphics/preview.gif"/>
+            <file type="content_page" path="www/graphics/spacer.gif"/>
+            <file type="content_page" path="www/graphics/up.gif"/>
+            <file type="content_page" path="www/graphics/view.gif"/>
         </files>
         <parameters>
             <parameter datatype="number"  min_n_values="1"  max_n_values="1"  name="allow_question_deavtivation_p"  default="0" description="Allow questions to be set inactive"/>
Index: openacs-4/packages/survey/www/process-response.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/process-response.tcl,v
diff -u -r1.10 -r1.11
--- openacs-4/packages/survey/www/process-response.tcl	30 Dec 2002 02:49:45 -0000	1.10
+++ openacs-4/packages/survey/www/process-response.tcl	16 Jan 2003 14:04:17 -0000	1.11
@@ -73,7 +73,8 @@
 		    ad_complain "$errmsg: Please make sure your dates are valid."
 		}
 	    }
-  
+	   
+    
 	    if { [exists_and_not_null response_to_question($question_id)] } {
 
 		set response_value [string trim $response_to_question($question_id)]
@@ -195,16 +196,13 @@
 			db_dml survey_question_response_choice_insert "insert into survey_question_responses (response_id, question_id, choice_id)
  values (:response_id, :question_id, :response_value)"
 		    }
-
 		}
 		"shorttext" {
 		    db_dml survey_question_choice_shorttext_insert "insert into survey_question_responses (response_id, question_id, varchar_answer)
  values (:response_id, :question_id, :response_value)"
 		}
 		"boolean" {
-
 		    if { [empty_string_p $response_value] } {
-
 			set response_value [db_null]
 		    }
 
Index: openacs-4/packages/survey/www/process-response.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/process-response.xql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/survey/www/process-response.xql	25 Sep 2002 00:43:42 -0000	1.2
+++ openacs-4/packages/survey/www/process-response.xql	16 Jan 2003 14:04:18 -0000	1.3
@@ -1,6 +1,13 @@
 <?xml version="1.0"?>
 <queryset>
 
+<fullquery name="get_response_count">
+    <querytext>
+	select count(*) from survey_responses
+	where response_id=:new_response_id
+    </querytext>
+</fullquery>
+
 <fullquery name="section_exists">      
       <querytext>
       
Index: openacs-4/packages/survey/www/respond.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/respond.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/survey/www/respond.tcl	30 Nov 2002 17:51:03 -0000	1.3
+++ openacs-4/packages/survey/www/respond.tcl	16 Jan 2003 14:04:18 -0000	1.4
@@ -63,7 +63,8 @@
 
 # build a list containing the HTML (generated with survey_question_display) for each question
 set rownum 0
-    
+# for double-click protection
+set new_response_id [db_nextval acs_object_id_seq]    
 set questions [list]
 
 db_foreach survey_sections {} {
@@ -81,6 +82,6 @@
 	set return_url {}
     }
 }
-set form_vars [export_form_vars section_id survey_id]
+set form_vars [export_form_vars section_id survey_id new_response_id]
 ad_return_template
 
Index: openacs-4/packages/survey/www/admin/responses-export-oracle.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/admin/responses-export-oracle.xql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/survey/www/admin/responses-export-oracle.xql	23 Nov 2002 05:18:16 -0000	1.2
+++ openacs-4/packages/survey/www/admin/responses-export-oracle.xql	16 Jan 2003 14:04:53 -0000	1.3
@@ -61,7 +61,8 @@
           r.creation_date,
           q.abstract_data_type,
           q.sort_order
-     from survey_questions q, (select initial_user_id as user_id, creation_date, response_id from survey_responses_latest rt where survey_id=:survey_id) r, cc_users u, survey_sections ss
+     from survey_questions q, (select initial_user_id as user_id, creation_date, response_id from survey_responses_latest rt where survey_id=:survey_id) r, (select p.email, u.first_names, u.last_name, u.person_id as user_id from parties
+p, persons u where p.party_id=u.person_id) u, survey_sections ss
      where ss.survey_id=:survey_id
      and q.section_id=ss.section_id
      and r.user_id = u.user_id) sq
Index: openacs-4/packages/survey/www/admin/responses-export-postgresql.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/admin/responses-export-postgresql.xql,v
diff -u -r1.1 -r1.2
--- openacs-4/packages/survey/www/admin/responses-export-postgresql.xql	31 Oct 2002 13:36:21 -0000	1.1
+++ openacs-4/packages/survey/www/admin/responses-export-postgresql.xql	16 Jan 2003 14:04:53 -0000	1.2
@@ -48,7 +48,8 @@
           r.creation_date,
           q.abstract_data_type,
           q.sort_order
-     from survey_questions q, (select initial_user_id as user_id, creation_date, response_id from survey_responses_latest where survey_id=:survey_id) r, cc_users u, survey_sections ss
+     from survey_questions q, (select initial_user_id as user_id, creation_date, response_id from survey_responses_latest where survey_id=:survey_id) r, (select p.email, u.first_names, u.last_name, u.person_id as user_id from parties
+p, persons u where p.party_id=u.person_id) u, survey_sections ss
      where ss.survey_id=:survey_id
      and q.section_id=ss.section_id
      and r.user_id=u.user_id) sq
Index: openacs-4/packages/survey/www/admin/responses-export.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/survey/www/admin/responses-export.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/survey/www/admin/responses-export.tcl	30 Nov 2002 17:51:45 -0000	1.3
+++ openacs-4/packages/survey/www/admin/responses-export.tcl	16 Jan 2003 14:04:53 -0000	1.4
@@ -31,7 +31,7 @@
 set question_id_list [list]
 set responses_table survey_responses
 
-set headline "email,first_names,last_name,user_id,submission_date,ip_address,response_id"
+set headline "email,first_names,last_name,user_id,submission_date,response_id"
 
 db_foreach get_question_data_types {} {
     lappend question_id_list $question_id
Index: openacs-4/packages/wp-slim/wp-slim.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/wp-slim/wp-slim.info,v
diff -u -r1.9 -r1.10
--- openacs-4/packages/wp-slim/wp-slim.info	23 Sep 2002 23:32:38 -0000	1.9
+++ openacs-4/packages/wp-slim/wp-slim.info	16 Jan 2003 14:06:56 -0000	1.10
@@ -99,7 +99,6 @@
             <file type="query_file" db_type="oracle" path="www/live-revision-set-oracle.xql"/>
             <file type="query_file" db_type="postgresql" path="www/live-revision-set-postgresql.xql"/>
             <file type="content_page" path="www/live-revision-set.tcl"/>
-            <file type="content_page" path="www/master.adp"/>
             <file type="content_page" path="www/pics/1white.gif"/>
             <file type="content_page" path="www/pics/arrow.gif"/>
             <file type="content_page" path="www/pics/down.gif"/>