root/trunk/pylucid_project/PyLucid/system/URLs.py

Revision 1707, 7.1 kB (checked in by JensDiemer, 4 months ago)

add PATH_INFO

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Rev LastChangedDate
Line 
1# -*- coding: utf-8 -*-
2"""
3    PyLucid URLs
4    ~~~~~~~~~~~~
5
6    The URLs class has some usefull methods for plugins to build links.
7    Also the class has some joined media path information, for create urls and
8    filesystem path to the media and internal page files.
9
10    The view put a instance in context["URLs"]. The BasePlugin bind the class
11    to self. So every plugin can easy access the methods with self.URLs.
12
13    more info: http://pylucid.org/_goto/62/self-URLs/
14
15    Last commit info:
16    ~~~~~~~~~~~~~~~~~
17    $LastChangedDate: $
18    $Rev: $
19    $Author: $
20
21    :copyleft: 2007 by the PyLucid team, see AUTHORS for more details.
22    :license: GNU GPL v3 or above, see LICENSE for more details.
23"""
24
25import os, posixpath
26
27from django.conf import settings
28from django.utils.http import urlquote_plus
29
30
31def add_trailing_slash(path):
32    """
33    >>> add_trailing_slash("/noSlash")
34    '/noSlash/'
35    >>> add_trailing_slash("/hasSlash/")
36    '/hasSlash/'
37    """
38    if path=="" or path[-1]!="/":
39        return path+"/"
40    else:
41        return path
42
43def join_url(base, parts=None, args=None):
44    """
45    -join the url parts >base<, >parts< and >args< together
46    -quote every part of the url
47    -Always add a trailing slash!
48
49    >>> join_url("1")
50    u'1/'
51    >>> join_url(1, [2,3])
52    u'1/2/3/'
53    >>> join_url("/1/", [2,3])
54    u'/1/2/3/'
55    >>> join_url("1", [2,3], ("/4/","/5/"))
56    u'1/2/3/4/5/'
57    """
58    def get_quoted_list(item, safe="/"):
59        """
60        -convert the item into a list
61        -quote every part of the list
62        """
63        if item == None:
64            return []
65        elif isinstance(item, tuple):
66            item_list = list(item)
67        elif isinstance(item, list):
68            item_list = item
69        else:
70            item_list = [item]
71
72        return [urlquote_plus(entry, safe) for entry in item_list]
73
74    # Note: base can start with e.g.: "http://foobar", so we set 'safe'
75    base = get_quoted_list(base, safe=':/')
76    parts = get_quoted_list(parts)
77    args = get_quoted_list(args)
78
79    # join all list parts together
80    part_list = base + parts + args
81
82    # sript every "/" out, but not for the first and the last entry:
83    index_list = range(len(part_list))[1:-1]
84    for index in index_list:
85        part_list[index] = part_list[index].strip("/")
86
87    # remove a trailing slash from the first item:
88    part_list[0] = part_list[0].rstrip("/")
89
90    # remove a leading slash from the last item:
91    part_list[-1] = part_list[-1].lstrip("/")
92
93    url = "/".join(part_list)
94    url = add_trailing_slash(url)
95
96    return url
97
98
99class URLs(dict):
100    def __init__(self, context):
101        self.context     = context
102        self.request     = context["request"]
103        self.page_msg    = self.request.page_msg
104
105        # Would be set by plugin_manager
106        self.current_plugin = None
107
108        self.setup_mediapath()
109        self.setup_URLs()
110
111    def setup_mediapath(self):
112        """
113        Set some shared used media path information to build url and filesystem
114        path to the media and internal page files.
115        About the internal_page stuff see DocString in system/internal_page.py
116        """
117        self["PyLucid_media_url"] = posixpath.join(
118            settings.MEDIA_URL,
119            settings.PYLUCID_MEDIA_DIR,
120        )
121        self["pylucid_media_root"] = os.path.join(
122            settings.MEDIA_ROOT,
123            settings.PYLUCID_MEDIA_DIR,
124        )
125        #----------------------------------------------------------------------
126        self["internal_page_url"] = posixpath.join(
127            self["PyLucid_media_url"],
128            settings.INTERNAL_PAGE_DIR,
129        )
130        self["internal_page_root"] = os.path.join(
131            self["pylucid_media_root"],
132            settings.INTERNAL_PAGE_DIR,
133        )
134        #----------------------------------------------------------------------
135        self["custom_internal_page_url"] = posixpath.join(
136            self["PyLucid_media_url"],
137            settings.CUSTOM_INTERNAL_PAGE_DIR,
138        )
139        self["custom_internal_page_root"] = os.path.join(
140            self["pylucid_media_root"],
141            settings.CUSTOM_INTERNAL_PAGE_DIR,
142        )
143
144    def setup_URLs(self):
145        """
146        Set some base urls, which are same for every Request and inside the
147        response would be built.
148        """
149        self["cwd"] = os.getcwdu()
150        self["host"] = self.request.get_host()
151        self["hostname"] = "%s://%s" % (
152            self.request.META.get('wsgi.url_scheme', "http"),
153            self["host"],
154        )
155
156        self["path_info"] = self.request.META.get("PATH_INFO", "")
157
158#        self["scriptRoot"] = self.request.META.get("SCRIPT_NAME", "/")
159        self["scriptRoot"] = "/"
160
161        self["docRoot"] = add_trailing_slash(posixpath.split(self["scriptRoot"])[0])
162
163        self["absoluteIndex"] = add_trailing_slash(
164            "".join((self["hostname"], self["scriptRoot"]))
165        )
166        self["adminBase"] = posixpath.join(
167            self["scriptRoot"], settings.ADMIN_URL_PREFIX
168        )
169
170    #__________________________________________________________________________
171
172    def get_command_base(self):
173        """
174        Generate the command base for self.commandLink() and self.methodLink().
175        Note: This is extra not build in self.setup_URLs(), because a Plugin
176        can change the current page!
177        e.g.: After a new page created, PyLucid goto this new page and every
178        command/method link should use the new page id.
179        """
180        return posixpath.join(
181            self["scriptRoot"], settings.COMMAND_URL_PREFIX,
182            str(self.context["PAGE"].id)
183        )
184
185    def commandLink(self, plugin_name, method_name, args=None):
186        """
187        generate a command link
188        """
189        command_base = self.get_command_base()
190        parts = [plugin_name, method_name]
191        return join_url(command_base, parts, args)
192
193    def methodLink(self, method_name, args=None):
194        """
195        generate a link to a other method in the current used plugin.
196        """
197        command_base = self.get_command_base()
198        parts = [self.current_plugin, method_name]
199        return join_url(command_base, parts, args)
200
201    def adminLink(self, url):
202        """
203        generate a link into the django admin panel.
204        """
205        return join_url(self["adminBase"], url)
206
207    #__________________________________________________________________________
208
209    def make_absolute_url(self, link):
210        """
211        make the given link to a absolute url.
212        """
213        return join_url(self["hostname"], link)
214
215    #__________________________________________________________________________
216
217    def debug(self):
218        """
219        write debug information into the page_msg
220        """
221        self.page_msg("URLs debug:")
222        for k,v in self.items():
223            self.page_msg(" - %15s: '%s'" % (k,v))
224
225
226
227def _doc_test(verbose):
228    global DEBUG
229    DEBUG = True
230
231    import doctest
232    doctest.testmod(verbose=verbose)
233
234
235if __name__ == "__main__":
236    print "Start a DocTest..."
237#    _doc_test(verbose=False)
238    _doc_test(verbose=True)
239    print "DocTest end."
240    print
241    print "Note:"
242    print "You should run ./dev_scripts/unittests/unittest_URLs.py !"
Note: See TracBrowser for help on using the browser.