sites/irclogs.qmsk.net/urls.py
author Tero Marttila <terom@fixme.fi>
Sat, 07 Feb 2009 20:34:07 +0200
branchsites
changeset 37 1f13c384508e
parent 36 02d4040d5946
child 38 9737b6ca2295
permissions -rw-r--r--
URLTree works, apart from trailing default values
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
    
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    78
    def match (self, value) :
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
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    81
            object, or boolean false to not match
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    82
        """
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    83
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    84
        abstract
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    85
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    86
class EmptyLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    87
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    88
        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
    89
    """
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
    def __eq__ (self, other) :
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
            Just compares type
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    94
        """
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
        return isinstance(other, EmptyLabel)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
    97
    
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    98
    def match (self, value) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
    99
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   100
            Match empty string -> True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   101
        """
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
        if value == '' :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   104
            return True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   105
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   106
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   107
        return ''
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   108
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   109
class StaticLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   110
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   111
        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
   112
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   113
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   114
    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
   115
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   116
    def __init__ (self, name) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   117
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   118
            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
   119
        """
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
        self.name = name
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   122
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   123
    def __eq__ (self, other) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   124
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   125
            Compares names
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   126
        """
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
        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
   129
    
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   130
    def match (self, value) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   131
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   132
            Match exactly -> True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   133
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   134
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   135
        if value == self.name :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   136
            return True
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   137
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   138
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   139
        return self.name
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   140
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   141
class ValueLabel (Label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   142
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   143
        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
   144
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   145
        XXX: do we even need this?
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   146
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   147
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   148
    def __init__ (self, key, default) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   149
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   150
            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
   151
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   152
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   153
        self.key = key
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   154
        self.default = default
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
    def __eq__ (self, other) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   157
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   158
            Compares keys
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
        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
   162
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   163
class SimpleValueLabel (ValueLabel) :
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
        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
   166
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   167
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   168
    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
   169
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   170
    def __init__ (self, key, default) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   171
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   172
            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
   173
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   174
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   175
        super(SimpleValueLabel, self).__init__(key, default)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   176
    
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   177
    def match (self, value) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   178
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   179
            Match -> LabelValue
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   180
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   181
            XXX: empty string?
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   182
        """
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   183
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   184
        return LabelValue(self, value)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   185
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   186
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   187
        if self.default :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   188
            return '{%s=%s}' % (self.key, self.default)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   189
            
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   190
        else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   191
            return '{%s}' % (self.key, )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   192
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   193
class URL (object) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   194
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   195
        Represents a specific URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   196
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   197
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   198
    def __init__ (self, url_mask, handler, **defaults) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   199
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   200
            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
   201
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   202
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   203
        # store
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   204
        self.url_mask = url_mask
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   205
        self.handler = handler
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   206
        self.defaults = defaults
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   207
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   208
        # build our labels
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   209
        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
   210
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   211
    def get_label_path (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   212
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   213
            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
   214
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   215
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   216
        # copy self.label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   217
        return list(self.label_path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   218
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   219
    def execute (self, request, label_values) :
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   220
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   221
            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
   222
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   223
        
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   224
        # start with the defaults
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   225
        kwargs = self.defaults()
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   226
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   227
        # then add all the values
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   228
        for label_value in label_values :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   229
            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
   230
            
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   231
        # execute the handler
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   232
        return self.handler(request, **kwargs)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   233
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   234
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   235
        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
   236
    
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   237
    def __repr__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   238
        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
   239
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   240
class URLNode (object) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   241
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   242
        Represents a node in the URLTree
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   243
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   244
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   245
    def __init__ (self, parent, label) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   246
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   247
            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
   248
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   249
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   250
        # the parent URLNode
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   251
        self.parent = parent
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   252
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   253
        # this node's Label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   254
        self.label = label
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   255
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   256
        # list of child URLNodes
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   257
        self.children = []
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
        # 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
   260
        self.url = None
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 _build_child (self, 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
            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
   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
        # build new child
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   268
        child = URLNode(self, label)
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
        # add to children
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   271
        self.children.append(child)
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
        # return
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   274
        return child
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
    def add_url (self, url, label_path) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   277
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   278
            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
   279
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   280
            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
   281
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   282
            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
   283
            url was assigned before.
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   284
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   285
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   286
        # matches this node?
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   287
        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
   288
            if self.url :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   289
                raise URLError(url, "node already defined")
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   290
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   291
            else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   292
                # set
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   293
                self.url = url
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
        else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   296
            # pop child label from label_path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   297
            child_label = label_path.pop(0)
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
            # look for the child to recurse into
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   300
            child = None
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
            # 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
   303
            for child in self.children :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   304
                if child.label == child_label :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   305
                    # found, use this
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   306
                    break
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
                # build a new child
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   310
                child = self._build_child(child_label)
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
            # 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
   313
            child.add_url(url, label_path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   314
    
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   315
    def match (self, label_path) :
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   316
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   317
            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
   318
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   319
            Returns a (url, label_values) tuple
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   320
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   321
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   322
        # empty label_path?
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   323
        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
   324
            # the search ends at this node
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   325
            if self.url :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   326
                # this URL is the best match
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   327
                return (self.url, [])
36
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
            else :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   330
                # incomplete URL
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   331
                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
   332
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   333
        else :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   334
            # 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
   335
            label = label_path.pop(0)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   336
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   337
            # return one match...
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   338
            match = value = None
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   339
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   340
            # recurse through our children
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   341
            for child in self.children :
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   342
                # match value
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   343
                value = child.label.match(label)
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   344
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   345
                # 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
   346
                if not value :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   347
                    continue;
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   348
                
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   349
                # already found a match? :/
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   350
                if match :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   351
                    raise URLError("Ambiguous URL")
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   352
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   353
                # 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
   354
                match = child
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   355
            
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   356
            # found something?
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   357
            if not match :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   358
                raise URLError("No child found for label")
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   359
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   360
            # ok, recurse into the match
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   361
            url, label_value = match.match(label_path)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   362
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   363
            # add our value?
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   364
            if isinstance(value, LabelValue) :
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   365
                label_value.append(value)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   366
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   367
            # return the match
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   368
            return url, label_value
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   369
    
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   370
    def dump (self, indent=0) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   371
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   372
            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
   373
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   374
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   375
        return '\n'.join([
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   376
            "%-45s%s" % (
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   377
                ' '*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
   378
                (' -> %r' % self.url) if self.url else ''
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   379
            )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   380
        ] + [
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   381
            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
   382
        ])
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   383
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   384
    def __str__ (self) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   385
        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
   386
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   387
class URLTree (map.Mapper) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   388
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   389
        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
   390
    """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   391
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   392
    def __init__ (self, url_list) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   393
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   394
            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
   395
        """
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
        # root node
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   398
        self.root = URLNode(None, EmptyLabel())
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   399
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   400
        # just add each URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   401
        for url in url_list :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   402
            self.add_url(url)
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
    def add_url (self, url) :
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
            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
   407
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   408
        # get url's label path
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   409
        path = url.get_label_path()
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   410
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   411
        # should begin with root
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   412
        root_label = path.pop(0)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   413
        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
   414
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   415
        # add to root
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   416
        self.root.add_url(url, path)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   417
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   418
    def match (self, url) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   419
        """
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   420
            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
   421
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   422
            Returns an (URL, [LabelValue]) tuple.
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   423
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   424
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   425
        # normalize the URL
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   426
        url = os.path.normpath(url)
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   427
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   428
        # split it into labels
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   429
        path = url.split('/')
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   430
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   431
        # ensure that it starts with a /
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   432
        root_label = path.pop(0)
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   433
        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
   434
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   435
        # just match starting at root
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   436
        return self.root.match(path)
36
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
    def handle_request (self, request) :
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   439
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   440
            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
   441
        """
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   442
        
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   443
        # get the request's URL path
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   444
        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
   445
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   446
        # let the URL handle it
37
1f13c384508e URLTree works, apart from trailing default values
Tero Marttila <terom@fixme.fi>
parents: 36
diff changeset
   447
        url.execute(request, label_values)
36
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   448
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   449
# urls
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   450
index           = URL(  '/',                                            handlers.index                                          )
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   451
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
   452
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
   453
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
   454
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   455
# mapper
02d4040d5946 start working on some nify URL parsing
Tero Marttila <terom@fixme.fi>
parents: 35
diff changeset
   456
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
   457