sites/irclogs.qmsk.net/urls.py
author Tero Marttila <terom@fixme.fi>
Sat, 07 Feb 2009 20:40:56 +0200
branchsites
changeset 38 9737b6ca2295
parent 37 1f13c384508e
child 39 82df0bb66ca7
permissions -rw-r--r--
working trailing defaults
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
"""
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
    URL mapping for the irclogs.qmsk.net site
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
"""
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
     6
import re
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
     7
import os.path
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
     8
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
# our own handlers
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
import handlers
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    12
# mapper
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    13
from lib import map
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    15
class URLError (Exception) :
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
    """
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    17
        Error with an URL definition
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    """
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    20
    pass
29
b06ff4c05d42 start prototyping some site-based code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    22
class LabelValue (object) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    23
    """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    24
        Represents the value of a ValueLabel...
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    25
    """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    26
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    27
    def __init__ (self, label, value) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    28
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    29
            Just store
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    30
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    31
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    32
        self.label = label
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    33
        self.value = value
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    34
    
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    35
    def __str__ (self) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    36
        return "%s=%s" % (self.label.key, self.value)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    38
    def __repr__ (self) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    39
        return "<%s>" % self
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    40
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    41
class Label (object) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    42
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    43
        Base class for URL labels (i.e. the segments of the URL between /s)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    44
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    45
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    46
    @staticmethod
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    47
    def parse (mask, defaults) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    48
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    49
            Parse the given label-segment, and return a *Label instance
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    50
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    51
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    52
        # empty?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    53
        if not mask :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    54
            return EmptyLabel()
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    55
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    56
        # simple value?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    57
        match = SimpleValueLabel.EXPR.match(mask)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    58
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    59
        if match :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    60
            # key
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    61
            key = match.group('key')
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    62
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    63
            # default?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    64
            default = defaults.get(key)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    65
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    66
            # build
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    67
            return SimpleValueLabel(key, default)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    68
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    69
        # static?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    70
        match = StaticLabel.EXPR.match(mask)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    71
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    72
        if match :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    73
            return StaticLabel(match.group('name'))
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    74
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    75
        # invalid
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    76
        raise URLError("Invalid label: %r" % (mask, ))
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    77
    
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    78
    def match (self, value=None) :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    79
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    80
            Match this label against the given value, returning either True to match without a value, a LabelValue
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    81
            object, or boolean false to not match.
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    82
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    83
            If value is None, this means that only a default value should be accepted. XXX: currently returned default
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    84
            is not used.
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    85
        """
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    86
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    87
        abstract
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    88
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    89
class EmptyLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    90
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    91
        An empty label, i.e. just a slash in the URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    92
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    93
    
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    94
    def __eq__ (self, other) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    95
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    96
            Just compares type
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    97
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    98
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    99
        return isinstance(other, EmptyLabel)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   100
    
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   101
    def match (self, value=None) :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   102
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   103
            Match empty string -> True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   104
        """
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   105
        
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   106
        # no default
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   107
        if value is None :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   108
            return False
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   109
        
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   110
        # only empty segments
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   111
        if value == '' :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   112
            return True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   113
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   114
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   115
        return ''
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   116
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   117
class StaticLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   118
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   119
        A simple literal Label, used for fixed terms in the URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   120
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   121
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   122
    EXPR = re.compile(r'^(?P<name>[a-zA-Z_.-]+)$')
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   123
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   124
    def __init__ (self, name) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   125
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   126
            The given name is the literal name of this label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   127
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   128
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   129
        self.name = name
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   130
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   131
    def __eq__ (self, other) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   132
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   133
            Compares names
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   134
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   135
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   136
        return isinstance(other, StaticLabel) and self.name == other.name
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   137
    
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   138
    def match (self, value=None) :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   139
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   140
            Match exactly -> True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   141
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   142
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   143
        # no defaults
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   144
        if value is None :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   145
            return False
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   146
        
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   147
        # match name
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   148
        if value == self.name :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   149
            return True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   150
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   151
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   152
        return self.name
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   153
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   154
class ValueLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   155
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   156
        A label with a key and a value
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   157
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   158
        XXX: do we even need this?
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   159
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   160
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   161
    def __init__ (self, key, default) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   162
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   163
            Set the key and default value. Default value may be None if there is no default value defined
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   164
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   165
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   166
        self.key = key
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   167
        self.default = default
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   168
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   169
    def __eq__ (self, other) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   170
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   171
            Compares keys
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   172
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   173
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   174
        return isinstance(other, ValueLabel) and self.key == other.key
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   175
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   176
class SimpleValueLabel (ValueLabel) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   177
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   178
        A label that has a name and a simple string value
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   179
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   180
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   181
    EXPR = re.compile(r'^\{(?P<key>[a-zA-Z_][a-zA-Z0-9_]*)\}$')
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   182
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   183
    def __init__ (self, key, default) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   184
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   185
            The given key is the name of this label's value
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   186
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   187
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   188
        super(SimpleValueLabel, self).__init__(key, default)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   189
    
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   190
    def match (self, value=None) :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   191
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   192
            Match -> LabelValue
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   193
        """
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   194
        
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   195
        # default?
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   196
        if value is None and self.default :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   197
            return LabelValue(self, self.default)
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   198
        
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   199
        # only non-empty values!
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   200
        elif value :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   201
            return LabelValue(self, value)
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   202
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   203
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   204
        if self.default :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   205
            return '{%s=%s}' % (self.key, self.default)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   206
            
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   207
        else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   208
            return '{%s}' % (self.key, )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   209
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   210
class URL (object) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   211
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   212
        Represents a specific URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   213
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   214
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   215
    def __init__ (self, url_mask, handler, **defaults) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   216
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   217
            Create an URL with the given url mask, handler, and default values
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   218
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   219
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   220
        # store
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   221
        self.url_mask = url_mask
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   222
        self.handler = handler
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   223
        self.defaults = defaults
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   224
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   225
        # build our labels
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   226
        self.label_path = [Label.parse(mask, defaults) for mask in url_mask.split('/')]
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   227
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   228
    def get_label_path (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   229
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   230
            Returns a list containing the labels in this url
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   231
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   232
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   233
        # copy self.label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   234
        return list(self.label_path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   235
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   236
    def execute (self, request, label_values) :
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   237
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   238
            Invoke the handler, using the given label values
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   239
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   240
        
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   241
        # start with the defaults
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   242
        kwargs = self.defaults()
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   243
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   244
        # then add all the values
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   245
        for label_value in label_values :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   246
            kwargs[label_value.label.key] = label_value.value
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   247
            
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   248
        # execute the handler
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   249
        return self.handler(request, **kwargs)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   250
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   251
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   252
        return '/'.join(str(label) for label in self.label_path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   253
    
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   254
    def __repr__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   255
        return "URL(%r, %r)" % (str(self), self.handler)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   256
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   257
class URLNode (object) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   258
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   259
        Represents a node in the URLTree
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   260
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   261
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   262
    def __init__ (self, parent, label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   263
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   264
            Initialize with the given parent and label, empty children dict
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   265
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   266
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   267
        # the parent URLNode
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   268
        self.parent = parent
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   269
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   270
        # this node's Label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   271
        self.label = label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   272
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   273
        # list of child URLNodes
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   274
        self.children = []
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   275
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   276
        # this node's URL, set by add_url for an empty label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   277
        self.url = None
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   278
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   279
    def _build_child (self, label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   280
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   281
            Build, insert and return a new child Node
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   282
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   283
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   284
        # build new child
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   285
        child = URLNode(self, label)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   286
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   287
        # add to children
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   288
        self.children.append(child)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   289
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   290
        # return
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   291
        return child
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   292
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   293
    def add_url (self, url, label_path) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   294
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   295
            Add a URL object to this node under the given path. Uses recursion to process the path.
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   296
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   297
            The label_path argument is a (partial) label path as returned by URL.get_label_path.
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   298
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   299
            If label_path is empty (len zero, or begins with EmptyLabel), then the given url is assigned to this node, if no
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   300
            url was assigned before.
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   301
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   302
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   303
        # matches this node?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   304
        if not label_path or isinstance(label_path[0], EmptyLabel) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   305
            if self.url :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   306
                raise URLError(url, "node already defined")
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   307
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   308
            else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   309
                # set
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   310
                self.url = url
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   311
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   312
        else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   313
            # pop child label from label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   314
            child_label = label_path.pop(0)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   315
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   316
            # look for the child to recurse into
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   317
            child = None
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   318
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   319
            # look for an existing child with that label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   320
            for child in self.children :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   321
                if child.label == child_label :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   322
                    # found, use this
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   323
                    break
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   324
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   325
            else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   326
                # build a new child
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   327
                child = self._build_child(child_label)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   328
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   329
            # recurse to handle the rest of the label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   330
            child.add_url(url, label_path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   331
    
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   332
    def match (self, label_path) :
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   333
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   334
            Locate the URL object corresponding to the given label_path value under this node.
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   335
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   336
            Returns a (url, label_values) tuple
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   337
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   338
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   339
        # empty label_path?
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   340
        if not label_path or label_path[0] == '' :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   341
            # the search ends at this node
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   342
            if self.url :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   343
                # this URL is the best match
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   344
                return (self.url, [])
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   345
            
38
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   346
            # look for default-only values, DFS
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   347
            for child in self.children :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   348
                # does the child's label accept a default match?
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   349
                if child.label.match() :
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   350
                    return child.match(label_path)
9737b6ca2295 working trailing defaults
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
   351
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   352
            else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   353
                # incomplete URL
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   354
                raise URLError("no URL handler defined for this Node")
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   355
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   356
        else :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   357
            # pop the next label from the label path
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   358
            label = label_path.pop(0)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   359
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   360
            # return one match...
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   361
            match = value = None
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   362
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   363
            # recurse through our children
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   364
            for child in self.children :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   365
                # match value
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   366
                value = child.label.match(label)
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   367
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   368
                # skip those that don't match at all
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   369
                if not value :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   370
                    continue;
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   371
                
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   372
                # already found a match? :/
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   373
                if match :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   374
                    raise URLError("Ambiguous URL")
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   375
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   376
                # ok, but continue looking to make sure there's no ambiguous URLs
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   377
                match = child
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   378
            
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   379
            # found something?
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   380
            if not match :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   381
                raise URLError("No child found for label")
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   382
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   383
            # ok, recurse into the match
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   384
            url, label_value = match.match(label_path)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   385
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   386
            # add our value?
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   387
            if isinstance(value, LabelValue) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   388
                label_value.append(value)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   389
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   390
            # return the match
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   391
            return url, label_value
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   392
    
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   393
    def dump (self, indent=0) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   394
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   395
            Returns a multi-line string representation of this Node
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   396
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   397
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   398
        return '\n'.join([
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   399
            "%-45s%s" % (
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   400
                ' '*indent + str(self.label) + ('/' if self.children else ''), 
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   401
                (' -> %r' % self.url) if self.url else ''
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   402
            )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   403
        ] + [
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   404
            child.dump(indent + 4) for child in self.children
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   405
        ])
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   406
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   407
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   408
        return "%s/[%s]" % (self.label, ','.join(str(child) for child in self.children))
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   409
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   410
class URLTree (map.Mapper) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   411
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   412
        Map requests to handlers, using a defined tree of URLs
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   413
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   414
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   415
    def __init__ (self, url_list) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   416
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   417
            Initialize the tree using the given list of URLs
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   418
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   419
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   420
        # root node
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   421
        self.root = URLNode(None, EmptyLabel())
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   422
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   423
        # just add each URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   424
        for url in url_list :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   425
            self.add_url(url)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   426
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   427
    def add_url (self, url) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   428
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   429
            Adds the given URL to the tree. The URL must begin with a root slash.
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   430
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   431
        # get url's label path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   432
        path = url.get_label_path()
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   433
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   434
        # should begin with root
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   435
        root_label = path.pop(0)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   436
        assert root_label == self.root.label, "URL must begin with root"
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   437
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   438
        # add to root
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   439
        self.root.add_url(url, path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   440
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   441
    def match (self, url) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   442
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   443
            Find the URL object best corresponding to the given url, matching any ValueLabels.
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   444
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   445
            Returns an (URL, [LabelValue]) tuple.
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   446
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   447
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   448
        # normalize the URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   449
        url = os.path.normpath(url)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   450
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   451
        # split it into labels
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   452
        path = url.split('/')
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   453
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   454
        # ensure that it starts with a /
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   455
        root_label = path.pop(0)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   456
        assert self.root.label.match(root_label), "URL must begin with root"
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   457
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   458
        # just match starting at root
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   459
        return self.root.match(path)
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   460
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   461
    def handle_request (self, request) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   462
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   463
            Looks up the request's URL, and invokes its handler
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   464
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   465
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   466
        # get the request's URL path
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   467
        url, label_values = self.match(request.get_page_name())
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   468
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   469
        # let the URL handle it
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   470
        url.execute(request, label_values)
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   471
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   472
# urls
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   473
index           = URL(  '/',                                            handlers.index                                          )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   474
channel_view    = URL(  '/channel/{channel}',                           handlers.channel_view                                   )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   475
channel_last    = URL(  '/channel/{channel}/last/{count}/{format}',     handlers.channel_last,      count=100, format="html"    )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   476
channel_search  = URL(  '/channel/{channel}/search',                    handlers.channel_search                                 )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   477
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   478
# mapper
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   479
mapper = URLTree([index, channel_view, channel_last, channel_search])
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   480