[Zope-dev] Maybe not Aquisition :-( Help!

Chris Withers chrisw@nipltd.com
Fri, 01 Sep 2000 16:37:26 +0100


Brian, Shane and anyone else who's interested...

Help! I'm dying here ;-)
(and yes, I know it's a Friday)

Chris Withers wrote:
> > Are you certain that you are not losing the acquistion context
> > on your Articles somehow?

Well, okay, I don't think so... here's the source causing the problem:

<dtml-if site_item_list>  
<dtml-in site_item_list>  
<dtml-if "subject_image(subject)">woohoo!</dtml-if>  
</dtml-in site_item_list>  
</dtml-if site_item_list> 

And here's the traceback with my (hopefully helpful ;-) comments:

> Traceback (innermost last):
>              File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 222, in publish_module
>              File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 187, in publish
>              File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 171, in publish
>              File E:\Zope\227194~1.0\lib\python\ZPublisher\mapply.py, line 160, in mapply
>                (Object: index_html)

index_html is a DTML method, than contains <dtml-var site_header>.
It lives in the Squishdot Site object, which also contains the articles and other stuff.
If you want real details, see Squishdot.py in Squishdot 0.7.0...

>              File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 112, in call_object
>                (Object: index_html)
>              File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 167, in __call__
>                (Object: index_html)
>              File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_String.py, line 502, in __call__
>                (Object: index_html)
>              File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 163, in __call__
>                (Object: site_header)

So here's site_header, also a DTML method...

>              File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_String.py, line 502, in __call__
>                (Object: site_header)
>              File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_In.py, line 691, in renderwob
>                (Object: site_item_list)

I presume this means we're inside the the <dtml-in> now? What would the <dtml-if> show in this traceback?
(if anything...)

>              File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_Util.py, line 331, in eval
>                (Object: subject_image(subject))
>                (Info: subject)

Okay, so here's the source of the problem... I guess this 'subejct' comes from the namespace provided by 
the <dtml-in> over site_item_list... sound about right? ('subject' can't be acquired from the containing 
SquishSite object, SquishSite's don't have an attribute with that name ;-).

Right, here's site_item_list:

    # protected by 'View' permission
    def site_item_list(self):     
        # """ returns latest articles from today """     
        currtime =   int(time())     
        return map(lambda x, p=self: x.__of__(p), self.data.map(self.site_id_list(currtime)))     
                                     ^^^^^^^^^^^
                                     So it looks like at least an attempt at wrapping has been done...

See the PPS for the explanation of what site_id_list does :S
(short version: returns a list of article ids (integers), lots of contortions about which ids are picked :S)

Which raises the question of what self.data.map does...

Okay self.data is an IOBTree containing all the articles in the site (unwrapped, I think)
So I'm guessing data.map takes a list of integers and returns the appropriate article objects.
Funky, Shane, I know both you and I have wondered what that did ;-)

Anyway, taking that in mind, it would suggest the article objects being returned are wrapped in the context of 
self, which is the Squishdot Site object, which is just a 'normal' Acquisition.Implicit Zope object. So, I don't 
think it's acquisition wrapping or lack of it which is the problem, unless anyone can tell me better...

>              File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 189, in validate
>                (Object: index_html)
>              File E:\Zope\227194~1.0\lib\python\AccessControl\SecurityManager.py, line 139, in validate
>              File E:\Zope\227194~1.0\lib\python\AccessControl\ZopeSecurityPolicy.py, line 159, in validate
>            Unauthorized: subject

So anyway, subject is a string attribute of the (wrapped) article objects being returned by site_item_list().

I guess how it's being got is through an InstanceDict for the Article being plopped on the namespace stack and 'subject' being used as a key to this dictionary. Can anyone think of any nastiness happening here?

If not, I'm at a loss :(

I really hope someone can help/explain further,

cheers,

Chris

PS: What does the following mean? (seen a lot when editing and browsing stuff in Zope through FTP)
2000-09-01T14:55:20 PROBLEM(100) ZServer unhandled connect event

PPS: 

    site_id_list__roles__=[]
    def site_id_list(self, currtime):     
        # """ returns latest id list from currtime  """     
        ilist = self.id_list(currtime)     
        tdict = {}     
        tlist = []     
        ilen = len(ilist)     
        cnt = 0      
        while (cnt < ilen) and (len(tdict) < 5):     
            id = ilist[cnt]     
            item = self.data[id]     
            if tdict.has_key(item.subject):     
                pass     
            else:     
                tdict[item.subject] = id     
                tlist.append(id)     
            cnt = cnt + 1     
     
        return tlist 

so, we need id_list:

    id_list__roles__=[]
    def id_list(self, currtime):     
        # ''' returns id list of latest articles at currtime '''     
        rlist = self.rev_id_list()     
        max = self.max_itemlist     
        min = max / 3     
        rlen = len(rlist)     
        if rlen <= min:     
            pass # take all elements     
        else:     
            today_list = self.date_id_list(currtime)  # take only items from today     
            tlen = len(today_list)     
            if tlen <= min:     
                rlist = rlist[:min] # take minimum elements even though some items came from yesterday     
            else:     
                if tlen >= max:     
                    rlist = today_list[:max]  # take maximum elements from today                        
                else:     
                    rlist = today_list # take entire list of items from today     
        return rlist     

great, so now we need rev_id_list :S :

    rev_id_list__roles__=[]
    def rev_id_list(self):     
        # """ returns reversed id list of reviewed articles  """     
        rlist = map(None,self.ids)     
        rlist = filter(lambda x,p=self : p.data[x].reviewed, rlist)     
        rlist.reverse()     
        return rlist 

I'm 90% sure self.ids is an intSet containing the ids of the postings attached to the current posting (or the SquishSite in this case...)

self.data is covered above already...