Revision 1713c946

b/pithos/api/functions.py
42 42
from django.utils.encoding import smart_str
43 43
from xml.dom import minidom
44 44

  
45
from pithos.lib.filter import parse_filters
46

  
45 47
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound, Conflict,
46 48
    LengthRequired, PreconditionFailed, RequestEntityTooLarge, RangeNotSatisfiable, UnprocessableEntity)
47 49
from pithos.api.util import (rename_meta_key, format_header_key, printable_header_dict, get_account_headers,
......
494 496
    
495 497
    keys = request.GET.get('meta')
496 498
    if keys:
497
        keys = keys.split(',')
498
        l = [smart_str(x) for x in keys if x.strip() != '']
499
        keys = [format_header_key('X-Object-Meta-' + x.strip()) for x in l]
499
        keys = [smart_str(x.strip()) for x in keys.split(',') if x.strip() != '']
500
        included, excluded, opers = parse_filters(keys)
501
        keys = []
502
        keys += [format_header_key('X-Object-Meta-' + x) for x in included]
503
        keys += [format_header_key('!X-Object-Meta-' + x) for x in excluded]
504
        keys += ['%s%s%s' % (format_header_key('X-Object-Meta-' + k), o, v) for k, o, v in opers]
500 505
    else:
501 506
        keys = []
502 507
    
b/pithos/backends/base.py
289 289
            
290 290
            'keys': Include objects that satisfy the key queries in the list.
291 291
                    Use 'key', '!key' for existence queries, 'key op value' for
292
                    value queries, where 'op' can be one of ==, != <=, >=, <, >
292
                    value queries, where 'op' can be one of =, != <=, >=, <, >
293 293
            
294 294
            'shared': Only list objects with permissions set
295 295
        
b/pithos/backends/lib/sqlite/node.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
import re
35

  
36 34
from time import time
37 35

  
38 36
from dbworker import DBWorker
39 37

  
38
from pithos.lib.filter import parse_filters
39

  
40 40

  
41 41
ROOTNODE  = 0
42 42

  
......
80 80
    return s
81 81

  
82 82

  
83
_regexfilter = re.compile('(!?)\s*([\w-]+)\s*(==|!=|<=|>=|<|>)?\s*(.*)$', re.UNICODE)
84

  
85 83
_propnames = {
86 84
    'serial'    : 0,
87 85
    'node'      : 1,
......
593 591
             "where serial = ?")
594 592
        self.execute(q, (dest, source))
595 593
    
596
    def _parse_filters(self, filterq):
597
        preterms = filterq.split(',')
598
        included = []
599
        excluded = []
600
        opers = []
601
        match = _regexfilter.match
602
        for term in preterms:
603
            m = match(term)
604
            if m is None:
605
                continue
606
            neg, key, op, value = m.groups()
607
            if neg:
608
                excluded.append(key)
609
            elif not value:
610
                included.append(key)
611
            elif op:
612
                opers.append((key, op, value))
613
        
614
        return included, excluded, opers
615
    
616 594
    def _construct_filters(self, filterq):
617 595
        if not filterq:
618 596
            return None, None
619 597
        
620 598
        subqlist = []
621 599
        append = subqlist.append
622
        included, excluded, opers = self._parse_filters(filterq)
600
        included, excluded, opers = parse_filters(filterq.split(','))
623 601
        args = []
624 602
        
625 603
        if included:
......
721 699
                   
722 700
                   key ?op value
723 701
                       the attribute with this key satisfies the value
724
                       where ?op is one of ==, != <=, >=, <, >.
702
                       where ?op is one of =, != <=, >=, <, >.
725 703
           
726 704
           The list of common prefixes includes the prefixes
727 705
           matching up to the first delimiter after prefix,
b/pithos/lib/filter.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
import re
35

  
36

  
37
_regexfilter = re.compile('(!?)\s*([\w-]+)\s*(=|!=|<=|>=|<|>)?\s*(.*)$', re.UNICODE)
38

  
39

  
40
def parse_filters(terms):
41
    included = []
42
    excluded = []
43
    opers = []
44
    match = _regexfilter.match
45
    for term in terms:
46
        m = match(term)
47
        if m is None:
48
            continue
49
        neg, key, op, value = m.groups()
50
        if neg:
51
            excluded.append(key)
52
        elif not value:
53
            included.append(key)
54
        elif op:
55
            opers.append((key, op, value))
56

  
57
    return included, excluded, opers

Also available in: Unified diff