Imported Upstream version 12.1.0
[contrib/python-twisted.git] / twisted / python / urlpath.py
1 # -*- test-case-name: twisted.test.test_paths -*-
2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 #
6
7 import urlparse
8 import urllib
9
10 class URLPath:
11     def __init__(self, scheme='', netloc='localhost', path='',
12                  query='', fragment=''):
13         self.scheme = scheme or 'http'
14         self.netloc = netloc
15         self.path = path or '/'
16         self.query = query
17         self.fragment = fragment
18
19     _qpathlist = None
20     _uqpathlist = None
21     
22     def pathList(self, unquote=0, copy=1):
23         if self._qpathlist is None:
24             self._qpathlist = self.path.split('/')
25             self._uqpathlist = map(urllib.unquote, self._qpathlist)
26         if unquote:
27             result = self._uqpathlist
28         else:
29             result = self._qpathlist
30         if copy:
31             return result[:]
32         else:
33             return result
34
35     def fromString(klass, st):
36         t = urlparse.urlsplit(st)
37         u = klass(*t)
38         return u
39
40     fromString = classmethod(fromString)
41
42     def fromRequest(klass, request):
43         return klass.fromString(request.prePathURL())
44
45     fromRequest = classmethod(fromRequest)
46
47     def _pathMod(self, newpathsegs, keepQuery):
48         if keepQuery:
49             query = self.query
50         else:
51             query = ''
52         return URLPath(self.scheme,
53                         self.netloc,
54                         '/'.join(newpathsegs),
55                         query)
56
57     def sibling(self, path, keepQuery=0):
58         l = self.pathList()
59         l[-1] = path
60         return self._pathMod(l, keepQuery)
61
62     def child(self, path, keepQuery=0):
63         l = self.pathList()
64         if l[-1] == '':
65             l[-1] = path
66         else:
67             l.append(path)
68         return self._pathMod(l, keepQuery)
69
70     def parent(self, keepQuery=0):
71         l = self.pathList()
72         if l[-1] == '':
73             del l[-2]
74         else:
75             # We are a file, such as http://example.com/foo/bar
76             # our parent directory is http://example.com/
77             l.pop()
78             l[-1] = ''
79         return self._pathMod(l, keepQuery)
80
81     def here(self, keepQuery=0):
82         l = self.pathList()
83         if l[-1] != '':
84             l[-1] = ''
85         return self._pathMod(l, keepQuery)
86
87     def click(self, st):
88         """Return a path which is the URL where a browser would presumably take
89         you if you clicked on a link with an HREF as given.
90         """
91         scheme, netloc, path, query, fragment = urlparse.urlsplit(st)
92         if not scheme:
93             scheme = self.scheme
94         if not netloc:
95             netloc = self.netloc
96             if not path:
97                 path = self.path
98                 if not query:
99                     query = self.query
100             elif path[0] != '/':
101                 l = self.pathList()
102                 l[-1] = path
103                 path = '/'.join(l)
104         
105         return URLPath(scheme,
106                         netloc,
107                         path,
108                         query,
109                         fragment)
110
111
112     
113     def __str__(self):
114         x = urlparse.urlunsplit((
115             self.scheme, self.netloc, self.path,
116             self.query, self.fragment))
117         return x
118
119     def __repr__(self):
120         return ('URLPath(scheme=%r, netloc=%r, path=%r, query=%r, fragment=%r)'
121                 % (self.scheme, self.netloc, self.path, self.query, self.fragment))
122