Package qm :: Package external :: Package DocumentTemplate :: Module DT_In
[hide private]
[frames] | no frames]

Source Code for Module qm.external.DocumentTemplate.DT_In

  1  ############################################################################## 
  2  #  
  3  # Zope Public License (ZPL) Version 1.0 
  4  # ------------------------------------- 
  5  #  
  6  # Copyright (c) Digital Creations.  All rights reserved. 
  7  #  
  8  # This license has been certified as Open Source(tm). 
  9  #  
 10  # Redistribution and use in source and binary forms, with or without 
 11  # modification, are permitted provided that the following conditions are 
 12  # met: 
 13  #  
 14  # 1. Redistributions in source code must retain the above copyright 
 15  #    notice, this list of conditions, and the following disclaimer. 
 16  #  
 17  # 2. Redistributions in binary form must reproduce the above copyright 
 18  #    notice, this list of conditions, and the following disclaimer in 
 19  #    the documentation and/or other materials provided with the 
 20  #    distribution. 
 21  #  
 22  # 3. Digital Creations requests that attribution be given to Zope 
 23  #    in any manner possible. Zope includes a "Powered by Zope" 
 24  #    button that is installed by default. While it is not a license 
 25  #    violation to remove this button, it is requested that the 
 26  #    attribution remain. A significant investment has been put 
 27  #    into Zope, and this effort will continue if the Zope community 
 28  #    continues to grow. This is one way to assure that growth. 
 29  #  
 30  # 4. All advertising materials and documentation mentioning 
 31  #    features derived from or use of this software must display 
 32  #    the following acknowledgement: 
 33  #  
 34  #      "This product includes software developed by Digital Creations 
 35  #      for use in the Z Object Publishing Environment 
 36  #      (http://www.zope.org/)." 
 37  #  
 38  #    In the event that the product being advertised includes an 
 39  #    intact Zope distribution (with copyright and license included) 
 40  #    then this clause is waived. 
 41  #  
 42  # 5. Names associated with Zope or Digital Creations must not be used to 
 43  #    endorse or promote products derived from this software without 
 44  #    prior written permission from Digital Creations. 
 45  #  
 46  # 6. Modified redistributions of any form whatsoever must retain 
 47  #    the following acknowledgment: 
 48  #  
 49  #      "This product includes software developed by Digital Creations 
 50  #      for use in the Z Object Publishing Environment 
 51  #      (http://www.zope.org/)." 
 52  #  
 53  #    Intact (re-)distributions of any official Zope release do not 
 54  #    require an external acknowledgement. 
 55  #  
 56  # 7. Modifications are encouraged but must be packaged separately as 
 57  #    patches to official Zope releases.  Distributions that do not 
 58  #    clearly separate the patches from the original work must be clearly 
 59  #    labeled as unofficial distributions.  Modifications which do not 
 60  #    carry the name Zope may be packaged in any form, as long as they 
 61  #    conform to all of the clauses above. 
 62  #  
 63  #  
 64  # Disclaimer 
 65  #  
 66  #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY 
 67  #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 68  #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 69  #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS 
 70  #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 71  #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 72  #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
 73  #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 74  #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 75  #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 76  #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 77  #   SUCH DAMAGE. 
 78  #  
 79  #  
 80  # This software consists of contributions made by Digital Creations and 
 81  # many individuals on behalf of Digital Creations.  Specific 
 82  # attributions are listed in the accompanying credits file. 
 83  #  
 84  ############################################################################## 
 85  '''Sequence insertion 
 86   
 87         A sequence may be inserted using an 'in' command.  The 'in' 
 88         command specifies the name of a sequence object and text to 
 89         be inserted for each element in the sequence.   
 90   
 91         The EPFS syntax for the in command is:: 
 92   
 93            %(in name)[ 
 94                 text 
 95            %(in name)] 
 96   
 97         The HTML syntax for the in command is:: 
 98   
 99            <!--#in name--> 
100                 text  
101            <!--#/in name--> 
102   
103        See the example below that shows how 'if', 'else', and 'in' commands 
104        may be combined to display a possibly empty list of objects. 
105   
106        The text included within an 'in' command will be refered to 
107        as an 'in' block. 
108   
109      Synopsis 
110   
111        If the variable 'sequence' exists as a sequence, a simple case 
112        of the 'in' tag is used as follows:: 
113   
114           <!--#in sequence-->some markup<!--#/in--> 
115   
116        A more complete case is used as follows:: 
117   
118          <!--#in sequence sort=age--> 
119            <!--#var sequence-number-->) <!--#var age--> 
120          <!--#/in--> 
121   
122      Attributes 
123   
124        sort -- Define the sort order for sequence items.  If an item in 
125        the sequence does not define  
126   
127        reverse -- Reverse the sequence (may be combined with sort).  Note 
128        that this can cause a huge memory use in lazy activation instances.  
129   
130        Within an 'in' block, variables are substituted from the 
131        elements of the iteration.  The elements may be either 
132        instance or mapping objects.  In addition, the variables: 
133   
134           'sequence-item' -- The element. 
135   
136           'sequence-var-nnn' -- The value of a specific named attribute 
137             of the item, where 'nnn' is the name.  For example, to get 
138             an items 'title' attribute, use 'sequence-var-title'.  This 
139             construct is most useful in an 'if' tag to test whether an 
140             attribute is present, because the attribute lookup will be 
141             extended to the full document template namespace. 
142   
143           'sequence-key' -- The key associated with the element in an 
144             items list. See below. 
145   
146           'sequence-index' -- The index, starting from 0, of the 
147             element within the sequence. 
148   
149           'sequence-number' -- The index, starting from 1, of the 
150             element within the sequence. 
151   
152           'sequence-letter' -- The index, starting from 'a', of the 
153             element within the sequence. 
154   
155           'sequence-Letter' -- The index, starting from 'A', of the 
156             element within the sequence. 
157   
158           'sequence-roman' -- The index, starting from 'i', of the 
159             element within the sequence. 
160   
161           'sequence-Roman' -- The index, starting from 'I', of the 
162             element within the sequence. 
163   
164           'sequence-start' -- A variable that is true if the element 
165             being displayed is the first of the displayed elements, 
166             and false otherwise. 
167   
168           'sequence-end' -- A variable that is true if the element 
169             being displayed is the last of the displayed elements, 
170             and false otherwise. 
171   
172        are defined for each element. 
173   
174        Normally, 'in' blocks are used to iterate over sequences of 
175        instances.  If the optional parameter 'mapping' is specified 
176        after the sequence name, then the elements of the sequence 
177        will be treated as mapping objects. 
178   
179        An 'in' command may be used to iterate over a sequence of 
180        dictionary items.  If the elements of the iteration are 
181        two-element tuples, then then the template code given in the 
182        'in' block will be applied to the second element of each 
183        tuple and may use a variable, 'sequence-key' to access the 
184        first element in each tuple. 
185   
186      Batch sequence insertion 
187   
188        When displaying a large number of objects, it is sometimes 
189        desireable to display just a sub-sequence of the data. 
190        An 'in' command may have optional parameters, 
191        as in:: 
192   
193            <!--#in values start=start_var size=7--> 
194   
195        The parameter values may be either integer literals or 
196        variable names. 
197   
198        Up to five parameters may be set: 
199   
200            'start'   -- The number of the first element to be shown, 
201                         where elements are numbered from 1. 
202   
203            'end'     -- The number of the last element to be shown, 
204                         where elements are numbered from 1. 
205   
206            'size'    -- The desired number of elements to be shown at 
207                         once. 
208   
209            'orphan'  -- The desired minimum number of objects to be 
210                         displayed.  The default value for this 
211                         parameter is 3. 
212   
213            'overlap' -- The desired overlap between batches. The 
214                         default is no overlap.      
215   
216        Typically, only 'start' and 'size' will be specified. 
217   
218        When batch insertion is used, several additional variables are 
219        defined for use within the sequence insertion text: 
220   
221            'sequence-query' -- The original query string given in a get 
222               request with the form variable named in the 'start' 
223               attribute removed.  This is extremely useful when 
224               building URLs to fetch another batch. 
225   
226               To see how this is used, consider the following example:: 
227   
228                   <!--#in search_results size=20 start=batch_start--> 
229   
230                      ... display rows 
231   
232                      <!--#if sequence-end--> <!--#if next-sequence--> 
233                        <a href="<!--#var URL-->/<!--#var sequence-query 
234                            -->&batch_start=<!--#var 
235                            next-sequence-start-number-->"> 
236                        (Next <!--#var next-sequence-size--> results) 
237                        </a> 
238                      <!--#/if--> <!--#/if--> 
239   
240                   <!--#/in--> 
241   
242               If the original URL is: 'foo/bar?x=1&y=2', then the 
243               rendered text (after row data are displated) will be:: 
244   
245                        <a href="foo/bar?x=1&y=2&batch_start=20"> 
246                        (Next 20 results) 
247                        </a> 
248   
249               If the original URL is: 'foo/bar?batch_start=10&x=1&y=2', 
250               then the rendered text (after row data are displated) 
251               will be:: 
252   
253                        <a href="foo/bar?x=1&y=2&batch_start=30"> 
254                        (Next 20 results) 
255                        </a> 
256   
257            'sequence-step-start-index' -- The index, starting from 0, 
258               of the start of the current batch. 
259   
260            'sequence-step-end-index' -- The index, starting from 0, of 
261               the end of the current batch. 
262   
263            'sequence-step-size' -- The batch size used. 
264   
265            'previous-sequence' -- This variable will be true when the 
266               first element is displayed and when the first element 
267               displayed is not the first element in the sequence. 
268   
269            'previous-sequence-start-index' -- The index, starting from 
270               0, of the start of the batch previous to the current 
271               batch. 
272   
273            'previous-sequence-end-index' -- The index, starting from 
274               0, of the end of the batch previous to the current 
275               batch. 
276   
277            'previous-sequence-size' -- The size of the batch previous to 
278               the current batch. 
279   
280            'previous-batches' -- A sequence of mapping objects 
281               containing information about all of the batches prior 
282               to the batch being displayed. 
283   
284               Each of these mapping objects include the following 
285               variables: 
286   
287                  batch-start-index -- The index, starting from 
288                     0, of the beginning of the batch. 
289   
290                  batch-end-index -- The index, starting from 
291                     0, of the end of the batch. 
292   
293                  batch-size -- The size of the batch. 
294   
295            'next-sequence' -- This variable will be true when the last 
296               element is displayed and when the last element 
297               displayed is not the last element in the sequence. 
298   
299            'next-sequence-start-index' -- The index, starting from 
300               0, of the start of the batch after the current 
301               batch. 
302   
303            'next-sequence-end-index' -- The index, starting from 
304               0, of the end of the batch after the current 
305               batch. 
306   
307            'next-sequence-size' -- The size of the batch after 
308               the current batch. 
309   
310            'next-batches' -- A sequence of mapping objects 
311               containing information about all of the batches after 
312               the batch being displayed. 
313   
314               Each of these mapping objects include the following 
315               variables: 
316   
317                  batch-start-index -- The index, starting from 
318                     0, of the beginning of the batch. 
319   
320                  batch-end-index -- The index, starting from 
321                     0, of the end of the batch. 
322   
323                  batch-size -- The size of the batch. 
324   
325        For each of the variables listed above with names ending in 
326        "-index", there are variables with names ending in "-number", 
327        "-roman", "-Roman", "-letter", and "-Letter" that are indexed 
328        from 1, "i", "I", "a", and "A", respectively.  In addition, 
329        for every one of these variables there are variables with 
330        names ending in "-var-xxx", where "xxx" is an element 
331        attribute name or key. 
332   
333      Summary statistics 
334   
335        When performing sequence insertion, special variables may be 
336        used to obtain summary statistics.  To obtain a summary 
337        statistic for a variable, use the variable name: 
338        'statistic-name', where 'statistic' is a statistic name and 
339        'name' is the name of a data variable. 
340   
341        Currently supported statistic names are: 
342   
343          total -- The total of numeric values. 
344   
345          count -- The total number of non-missing values. 
346   
347          min -- The minimum of non-missing values. 
348   
349          max -- The maximum of non-missing values. 
350   
351          median -- The median of non-missing values. 
352   
353          mean -- The mean of numeric values values. 
354   
355          variance -- The variance of numeric values computed with a 
356            degrees of freedom qeual to the count - 1. 
357   
358          variance-n -- The variance of numeric values computed with a 
359            degrees of freedom qeual to the count. 
360   
361          standard-deviation -- The standard deviation of numeric values 
362            computed with a degrees of freedom qeual to the count - 1. 
363   
364          standard-deviation-n -- The standard deviation of numeric 
365            values computed with a degrees of freedom qeual to the count. 
366   
367        Missing values are either 'None' or the attribute 'Value' 
368        of the module 'Missing', if present. 
369   
370      'else' continuation tag within in 
371   
372        An 'else' tag may be used as a continuation tag in the 'in' tag. 
373        The source after the 'else' tag is inserted if: 
374   
375          - The sequence given to the 'in' tag is of zero length, or 
376   
377          - The 'previous' attribute was used and their are no 
378            previous batches, or 
379   
380          - The 'next' attribute was used and their are no 
381            next batches, or 
382   
383  ''' #' 
384   
385  __rcs_id__='$Id: DT_In.py 1007 2007-02-10 01:07:28Z stefan $' 
386  __version__='$Revision: 1007 $'[11:-2] 
387   
388  from DT_Util import ParseError, parse_params, name_param, str 
389  from DT_Util import render_blocks, InstanceDict, ValidationError, VSEval, expr_globals 
390  import re 
391  from DT_InSV import sequence_variables, opt 
392  TupleType=type(()) 
393   
394 -class InFactory:
395 blockContinuations=('else',) 396 name='in' 397
398 - def __call__(self, blocks):
399 i=InClass(blocks) 400 if i.batch: return i.renderwb 401 else: return i.renderwob
402 403 In=InFactory() 404
405 -class InClass:
406 elses=None 407 expr=sort=batch=mapping=None 408 start_name_re=None 409 reverse=None 410 sort_expr=reverse_expr=None 411
412 - def __init__(self, blocks):
413 tname, args, section = blocks[0] 414 args=parse_params(args, name='', start='1',end='-1',size='10', 415 orphan='3',overlap='1',mapping=1, 416 skip_unauthorized=1, 417 previous=1, next=1, expr='', sort='', 418 reverse=1, sort_expr='', reverse_expr='') 419 self.args=args 420 has_key=args.has_key 421 422 if has_key('sort'): 423 self.sort=sort=args['sort'] 424 if sort=='sequence-item': self.sort='' 425 426 if has_key('sort_expr'): 427 self.sort_expr=VSEval.Eval(args['sort_expr'], expr_globals) 428 429 if has_key('reverse_expr'): 430 self.reverse_expr=VSEval.Eval(args['reverse_expr'], expr_globals) 431 432 if has_key('reverse'): 433 self.reverse=args['reverse'] 434 435 if has_key('mapping'): self.mapping=args['mapping'] 436 for n in 'start', 'size', 'end': 437 if has_key(n): self.batch=1 438 439 for n in 'orphan','overlap','previous','next': 440 if has_key(n) and not self.batch: 441 raise ParseError, ( 442 """ 443 The %s attribute was used but neither of the 444 <code>start</code>, <code>end</code>, or <code>size</code> 445 attributes were used. 446 """ % n, 'in') 447 448 if has_key('start'): 449 v=args['start'] 450 if type(v)==type(''): 451 try: int(v) 452 except: 453 self.start_name_re=re.compile( 454 '&+'+ 455 ''.join(["[%s]" % c for c in v])+ 456 '=[0-9]+&+') 457 458 name,expr=name_param(args,'in',1) 459 if expr is not None: expr=expr.eval 460 self.__name__, self.expr = name, expr 461 self.section=section.blocks 462 if len(blocks) > 1: 463 if len(blocks) != 2: raise ParseError, ( 464 'too many else blocks', 'in') 465 tname, args, section = blocks[1] 466 args=parse_params(args, name='') 467 if args: 468 ename=name_param(args) 469 if ename != name: 470 raise ParseError, ( 471 'name in else does not match in', 'in') 472 self.elses=section.blocks
473 474
475 - def renderwb(self, md):
476 expr=self.expr 477 name=self.__name__ 478 if expr is None: 479 sequence=md[name] 480 cache={ name: sequence } 481 else: 482 sequence=expr(md) 483 cache=None 484 485 if not sequence: 486 if self.elses: return render_blocks(self.elses, md) 487 return '' 488 489 if type(sequence) is type(''): 490 raise 'InError', ( 491 'Strings are not allowed as input to the in tag.') 492 493 494 section=self.section 495 params=self.args 496 497 mapping=self.mapping 498 499 if self.sort_expr is not None: 500 self.sort=self.sort_expr.eval(md) 501 sequence=self.sort_sequence(sequence) 502 elif self.sort is not None: 503 sequence=self.sort_sequence(sequence) 504 505 if self.reverse_expr is not None and self.reverse_expr.eval(md): 506 sequence=self.reverse_sequence(sequence) 507 elif self.reverse is not None: 508 sequence=self.reverse_sequence(sequence) 509 510 next=previous=0 511 try: start=int_param(params,md,'start',0) 512 except: start=1 513 end=int_param(params,md,'end',0) 514 size=int_param(params,md,'size',0) 515 overlap=int_param(params,md,'overlap',0) 516 orphan=int_param(params,md,'orphan','3') 517 start,end,sz=opt(start,end,size,orphan,sequence) 518 if params.has_key('next'): next=1 519 if params.has_key('previous'): previous=1 520 521 last=end-1 522 first=start-1 523 524 try: query_string=md['QUERY_STRING'] 525 except: query_string='' 526 527 vars=sequence_variables(sequence,'?'+query_string,self.start_name_re) 528 kw=vars.data 529 kw['mapping']=mapping 530 kw['sequence-step-size']=sz 531 kw['sequence-step-overlap']=overlap 532 kw['sequence-step-start']=start 533 kw['sequence-step-end']=end 534 kw['sequence-step-start-index']=start-1 535 kw['sequence-step-end-index']=end-1 536 kw['sequence-step-orphan']=orphan 537 538 push=md._push 539 pop=md._pop 540 render=render_blocks 541 542 if cache: push(cache) 543 push(vars) 544 try: 545 if previous: 546 if first > 0: 547 pstart,pend,psize=opt(0,first+overlap, 548 sz,orphan,sequence) 549 kw['previous-sequence']=1 550 kw['previous-sequence-start-index']=pstart-1 551 kw['previous-sequence-end-index']=pend-1 552 kw['previous-sequence-size']=pend+1-pstart 553 result=render(section,md) 554 555 elif self.elses: result=render(self.elses, md) 556 else: result='' 557 elif next: 558 try: 559 # The following line is a sneaky way to test whether 560 # there are more items, without actually 561 # computing a length: 562 sequence[end] 563 except IndexError: 564 if self.elses: result=render(self.elses, md) 565 else: result='' 566 else: 567 pstart,pend,psize=opt(end+1-overlap,0, 568 sz,orphan,sequence) 569 kw['next-sequence']=1 570 kw['next-sequence-start-index']=pstart-1 571 kw['next-sequence-end-index']=pend-1 572 kw['next-sequence-size']=pend+1-pstart 573 result=render(section,md) 574 else: 575 result = [] 576 append=result.append 577 validate=md.validate 578 for index in range(first,end): 579 if index==first and index > 0: 580 pstart,pend,psize=opt(0,index+overlap, 581 sz,orphan,sequence) 582 kw['previous-sequence']=1 583 kw['previous-sequence-start-index']=pstart-1 584 kw['previous-sequence-end-index']=pend-1 585 kw['previous-sequence-size']=pend+1-pstart 586 else: 587 kw['previous-sequence']=0 588 if index==last: 589 try: 590 # The following line is a sneaky way to 591 # test whether there are more items, 592 # without actually computing a length: 593 sequence[end] 594 pstart,pend,psize=opt(end+1-overlap,0, 595 sz,orphan,sequence) 596 kw['previous-sequence']=0 597 kw['next-sequence']=1 598 kw['next-sequence-start-index']=pstart-1 599 kw['next-sequence-end-index']=pend-1 600 kw['next-sequence-size']=pend+1-pstart 601 except: pass 602 603 if index==last: kw['sequence-end']=1 604 605 client=sequence[index] 606 607 if validate is not None: 608 try: vv=validate(sequence,sequence,None,client,md) 609 except: vv=0 610 if not vv: 611 if (params.has_key('skip_unauthorized') and 612 params['skip_unauthorized']): 613 if index==first: kw['sequence-start']=0 614 continue 615 raise ValidationError, index 616 617 kw['sequence-index']=index 618 if type(client)==TupleType and len(client)==2: 619 client=client[1] 620 621 if mapping: push(client) 622 else: push(InstanceDict(client, md)) 623 624 try: append(render(section, md)) 625 finally: pop(1) 626 627 if index==first: kw['sequence-start']=0 628 629 630 result=''.join(result) 631 632 finally: 633 if cache: pop() 634 pop() 635 636 return result
637
638 - def renderwob(self, md):
639 """RENDER WithOutBatch""" 640 expr=self.expr 641 name=self.__name__ 642 if expr is None: 643 sequence=md[name] 644 cache={ name: sequence } 645 else: 646 sequence=expr(md) 647 cache=None 648 649 if not sequence: 650 if self.elses: return render_blocks(self.elses, md) 651 return '' 652 653 if type(sequence) is type(''): 654 raise 'InError', ( 655 'Strings are not allowed as input to the in tag.') 656 657 section=self.section 658 mapping=self.mapping 659 660 661 if self.sort_expr is not None: 662 self.sort=self.sort_expr.eval(md) 663 sequence=self.sort_sequence(sequence) 664 elif self.sort is not None: 665 sequence=self.sort_sequence(sequence) 666 667 if self.reverse_expr is not None and self.reverse_expr.eval(md): 668 sequence=self.reverse_sequence(sequence) 669 elif self.reverse is not None: 670 sequence=self.reverse_sequence(sequence) 671 672 vars=sequence_variables(sequence) 673 kw=vars.data 674 kw['mapping']=mapping 675 676 l=len(sequence) 677 last=l-1 678 679 push=md._push 680 pop=md._pop 681 render=render_blocks 682 683 if cache: push(cache) 684 push(vars) 685 try: 686 result = [] 687 append=result.append 688 validate=md.validate 689 for index in range(l): 690 if index==last: kw['sequence-end']=1 691 client=sequence[index] 692 693 if validate is not None: 694 try: vv=validate(sequence,sequence,None,client,md) 695 except: vv=0 696 if not vv: 697 if (self.args.has_key('skip_unauthorized') and 698 self.args['skip_unauthorized']): 699 if index==1: kw['sequence-start']=0 700 continue 701 raise ValidationError, index 702 703 kw['sequence-index']=index 704 if type(client)==TupleType and len(client)==2: 705 client=client[1] 706 707 if mapping: push(client) 708 else: push(InstanceDict(client, md)) 709 710 try: append(render(section, md)) 711 finally: pop() 712 if index==0: kw['sequence-start']=0 713 714 result=''.join(result) 715 716 finally: 717 if cache: pop() 718 pop() 719 720 return result
721
722 - def sort_sequence(self, sequence):
723 724 # Modified with multiple sort fields by Ross Lazarus 725 # April 7 2000 rossl@med.usyd.edu.au 726 # eg <dtml in "foo" sort=akey,anotherkey> 727 728 sort=self.sort 729 sortfields = sort.split(',') # multi sort = key1,key2 730 multsort = len(sortfields) > 1 # flag: is multiple sort 731 mapping=self.mapping 732 isort=not sort 733 s=[] 734 for client in sequence: 735 k = None 736 if type(client)==TupleType and len(client)==2: 737 if isort: k=client[0] 738 v=client[1] 739 else: 740 if isort: k=client 741 v=client 742 743 if sort: 744 if multsort: # More than one sort key. 745 k = [] 746 for sk in sortfields: 747 try: 748 if mapping: akey = v[sk] 749 else: akey = getattr(v, sk) 750 except AttributeError, KeyError: akey = None 751 if not basic_type(akey): 752 try: akey = akey() 753 except: pass 754 k.append(akey) 755 else: # One sort key. 756 try: 757 if mapping: k = v[sort] 758 else: k = getattr(v, sort) 759 except AttributeError, KeyError: k = None 760 if not basic_type(k): 761 try: k = k() 762 except: pass 763 764 s.append((k,client)) 765 766 s.sort() 767 768 sequence=[] 769 for k, client in s: 770 sequence.append(client) 771 return sequence
772
773 - def reverse_sequence(self, sequence):
774 s=list(sequence) 775 s.reverse() 776 return s
777 778 779 basic_type={type(''): 1, type(0): 1, type(0.0): 1, type(()): 1, type([]): 1, 780 type(None) : 1 }.has_key 781
782 -def int_param(params,md,name,default=0, st=type('')):
783 try: v=params[name] 784 except: v=default 785 if v: 786 try: v=int(v) 787 except: 788 v=md[v] 789 if type(v) is st: v=int(v) 790 return v
791