Forum OpenACS Development: Getting package_id in an init.tcl script

I am adding the attachments facility to bulk mail, and have run into a logistical problem:

I want to mount up attachments under each instance of bulk-mail, just like dotlrn-forums does for forums.  I thought that the logical place to do this would be in bulk-mail-init.tcl, but there doesn't seem to be a way to get the package_id at that point.  All of the package_id getting schemes I can find rely on either using the package_key, which only works for a singleton, or ad_conn which doesn't work in an init script.

So, is there some way of getting the package_id that I've overlooked?  And if not, what is the preferred way/place to do this kind of thing?

Collapse
Posted by Roberto Mello on
Look at the site_node:: procs. You can probably find it using one of those procs.

-Roberto

Collapse
Posted by Janine Ohmer on
I've looked at them, but without a url or node_id I seem to be out of luck.  I'm pretty sure this isn't as hard as it seems to be - can anyone show me what I'm overlooking?  TIA!
Collapse
Posted by Don Baccus on
bulk-mail-init.tcl is only run when OpenACS is initializing itself, not every time bulk mail is mounted.

What you want to do is to make use of the APM callback stuff added in 4.6.3? 5.0 for sure ... there's an "after_mount" callback and the APM passes in the node_id of the new package instance for your convenience.

Collapse
Posted by Janine Ohmer on
Ok, I'm trying to do this but I'm obviously missing something.

I put this in bulk-mail/tcl/apm-callback-procs.tcl:

ad_library {
    APM callback procedures in the bulk-mail::apm namespace.

    @creation-date October 31 2003
    @author Janine Sisk
    @cvs-id $Id$
}

namespace eval bulk-mail::apm {}

ad_proc -public bulk-mail::apm::after_mount {
  {-package_id:required}
  {-node_id:required}
} {
  This is a comment about what this proc does
} {
  ns_log Notice "J9: in bulk_mail::apm::after_mount"
}

Then I created an after_mount callback for bulk-mail in the APM, using bulk-mail::apm::after_mount as the proc name, and restarted the site.  There are no errors in the error log, but my ns_log is not being executed.

What else do I need to do?

Collapse
Posted by Randy O'Meara on
Janine,

You should have to do nothing in addition to what you've done. I've done it exactly like this without any problem. If I recall, with debug on, the APM logs the fact that it's calling a callback.

The package manager shows that your callback is defined, right?

Collapse
Posted by Janine Ohmer on
Hi Randy,

Yes, the package manager shows that the callback is defined.  There don't seem to be too many ways to screw this up! :)

I am doing this in a 4.6.3 install, and I'm wondering if perhaps it's a feature that wasn't fully implemented until later.  Don seemed to be unsure about that as well when he suggested it.  Is anyone using it successfully in 4.6.3?

Collapse
Posted by Randy O'Meara on
Janine,

I know it works in 4.6 tip because that's where I was working until just a few weeks ago. My notes indicate that I added callbacks (using 4.6) to a package in September, but I'm fairly certain that it was actually prior to that. Don't know how close that was to 4.6.3.

If you turn debug on and install/mount a package (say acs-subsite), I believe you should see apm log messages when it invokes a callback.

I'm looking at 5.0 api-doc and I see that you can exercise the callback mechanism through the apm api apm_invoke_callback_proc (and others). In fact, you can set/remove/get callback procs with the api. Worth a try...

Randy

Collapse
Posted by Janine Ohmer on
Finally getting back to this...

The after_mount callback does work if I mount a new instance of bulk-mail from the site-map.  But it does not happen when the site starts/restarts.  There must be some other mechanism other than site_node::mount mounting up the packages during site startup.  Can anyone point me in the right direction?

Collapse
Posted by Randy O'Meara on
Once a package is mounted it's always mounted.

As Don said, if you're trying to retrofit existing bulk-mail instances with attachments, an *-init.tcl file that searches the site-map for existing bulk-mail (without attachments child node) and instantiates attachments would work. You should only have to do this once to hit every existing bulk-mail node.

If you add code to the bulk-mail after-mount callback to instantiate attachments, each new (mounted) bulk-mail instance would automatically get attachments.

Procs that may be useful:
    site_node::get_children
    site_node::get_from_node_id
    site_node::instantiate_and_mount

Collapse
Posted by Don Baccus on
Why do you need it to happen on server restart?  The notion is that you'll define your after_mount callback, then every time the package is mounted by the APM it will mount notifications.

If you're needing to patch up an already-running site that has bulk mail mounted already you'll have to do some gnarly hacking around in your init code.  Remember it only gets called once, not once per mounted instance (*-init.tcl files are sourced by the bootstrapper) so you'll have to traverse the site map looking for bulk mail instance.

But you'd only have to do that once, you don't want to mount a new instance of attachments every time the server restarts!!!

Collapse
Posted by Janine Ohmer on
Thanks, the light is starting to dawn.

Attachments is a slightly different beast;  it appears to be a pseudo-singleton package.  It's only instantiated once, when it's mounted at /attachments during the dotlrn install, and then that one copy is mounted up each time dotlrn-forums is added to a new community.

I had thought that becuase it's different, I would need to manually mount it up each time, but it sounds like you all are saying that won't be necessary.  So I'll go off and look into that.

Collapse
Posted by Don Baccus on
I really dislike the way attachments was implemented BTW ... having to mount it for each package that uses it is bogus.
Collapse
Posted by Janine Ohmer on
I really dislike the way attachments was implemented BTW

Oh yes, and it gets worse.

attachments has a package parameter called RelativeUrl, which is set to 'attach'. and the script to be run is attach.tcl. So in forums, the URL to go to when setting up an attachment is forums/attach/attach (groan). Objectionable though it may be, this does work.

Unfortunately, although bulk mail is processed by the bulk-mail package, it is sent by the dotlrn package. So when dotlrn/www/spam.tcl wants to send the user off to attachments, it can't just use the proc helpfully provided by attachments to get it's URL, because that turns out to be just attach/attach (relative to the community URL, of course), when it needs to be bulk-mail/attach/attach.

My first thought was "no problem, I'll automatically update the package parameter when I mount the package under bulk-mail". But noooo.... since there's only one instantiation of attachments, there's only one copy of RelativeUrl. I can't change it without breaking it's use in forums.

The same problem creeps in again on the return_url that's passed in to attachments. It can't be relative, because at the time it's used it will be relative to bulk-mail, which is wrong since you're heading back to dotlrn/www/spam-send.tcl.

Right now I've "fixed" all this with regexps but it's not what I'd call an elegant solution.

Collapse
Posted by Janine Ohmer on
And just to add to the fun....

There is no mention in an e-mailed forum message that there is an attachment.  In fact, I'm pretty sure the instant notifications go into the queue before the attachment has even been chosen.  So it's perfectly ok for the URL to the attachment to be relative to its community, since it's never used outside of the community.

Enter bulk mail, which has the opposite requirement.  I think I will have to add a full_url field to attachments, or some such thing, because the URL to the attachment has to be usable from the e-mail message that's sent out.

And, last but not least, when you mount attachments you have to give it the folder_id of the file-storage folder to use for storing the attachments.  I'm trying to make this not depend on dotLRN, since bulk-mail and attachments can both theoretically be used without it, so my only obvious choice for the folder to use is the topmost root folder.  Ick.

Suggestions on better approaches welcome - I was hoping to make this something I could contribute to the toolkit, although as the kludges pile up I'm beginning to have doubts.