Ticket #11727: breadcrumbs_svn.diff

File breadcrumbs_svn.diff, 14.4 KB (added by Felipe 'chronos' Prenholato, 15 years ago)

Breadcrumbs diff based on rev. 11477 from trunk.

  • django/conf/global_settings.py

     
    398398
    399399# The list of directories to search for fixtures
    400400FIXTURE_DIRS = ()
     401
     402###############
     403# BREADCRUMBS #
     404###############
     405
     406# Enable/Disable breadcrumbs, default: disabled
     407BREADCRUMBS = False
     408BREADCRUMBS_AUTO_HOME = False
  • django/forms/fields.py

     
    436436try:
    437437    from django.conf import settings
    438438    URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT
     439    URL_VERIFY_EXIST_SOCKET_TIMEOUT = settings.URL_VERIFY_EXIST_SOCKET_TIMEOUT
    439440except ImportError:
    440441    # It's OK if Django settings aren't configured.
    441442    URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
     443    URL_VERIFY_EXIST_SOCKET_TIMEOUT = 10
    442444
    443445
    444446class FileField(Field):
     
    543545    default_error_messages = {
    544546        'invalid': _(u'Enter a valid URL.'),
    545547        'invalid_link': _(u'This URL appears to be a broken link.'),
     548        'invalid_timeout': _(u'This URL took to long to respond, appears to be broken.'),
    546549    }
    547550
    548551    def __init__(self, max_length=None, min_length=None, verify_exists=False,
     
    563566        if value == u'':
    564567            return value
    565568        if self.verify_exists:
     569            import socket
    566570            import urllib2
     571            import sys
    567572            headers = {
    568573                "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
    569574                "Accept-Language": "en-us,en;q=0.5",
     
    571576                "Connection": "close",
    572577                "User-Agent": self.user_agent,
    573578            }
     579            if sys.version_info[:2]<(2,6):
     580                def urlopen(req, timeout=None):
     581                    socket_default_timeout = socket.getdefaulttimeout()
     582                    socket.setdefaulttimeout(timeout)
     583                    try:
     584                        return urllib2.urlopen(req)
     585                    finally:
     586                        socket.setdefaulttimeout(socket_default_timeout)
     587            else:
     588                urlopen = urllib2.urlopen
     589
    574590            try:
    575591                req = urllib2.Request(value, None, headers)
    576                 u = urllib2.urlopen(req)
     592                u = urlopen(req, timeout=URL_VERIFY_EXIST_SOCKET_TIMEOUT)
    577593            except ValueError:
    578594                raise ValidationError(self.error_messages['invalid'])
    579             except: # urllib2.URLError, httplib.InvalidURL, etc.
     595            except Exception, e: # urllib2.URLError, httplib.InvalidURL, etc.
     596                if e.args and isinstance(e.args[0], socket.timeout):
     597                    raise ValidationError(self.error_messages['invalid_timeout'])
    580598                raise ValidationError(self.error_messages['invalid_link'])
    581599        return value
    582600
  • django/contrib/breadcrumbs/breadcrumbs.py

     
     1"""
     2Classes to add request.breadcrumbs as one class to have a list of breadcrumbs
     3TODO: maybe is better to move to contrib/breadcrumbs
     4"""
     5
     6from django.conf import settings
     7from django.utils.translation import ugettext_lazy as _
     8from django.utils.safestring import mark_safe
     9from django.utils.text import force_unicode
     10import sys
     11
     12class Singleton(object):
     13    """
     14    We use a simple singleton pattern in Breadcrumbs.
     15    Example from http://svn.ademar.org/code/trunk/junk-code/singleton_vs_borg.py
     16    """
     17    def __new__(cls, *args, **kwds):
     18        it = cls.__dict__.get("__it__")
     19        if it is not None:
     20            return it
     21        cls.__it__ = it = object.__new__(cls)
     22        it._1st_init(*args, **kwds)
     23        return it
     24
     25    def _1st_init(self, *args, **kwds):
     26        pass
     27
     28class BreadcrumbsInvalidFormat(Exception):
     29    """
     30    Simple exception that can be extended
     31    """
     32    pass
     33
     34class BreadcrumbsNotSet(Exception):
     35    """
     36    Raised in utils.breadcrumbs_for_flatpages when we not have breadcrumbs in
     37    request.
     38    """
     39    pass
     40
     41class Breadcrumb(object):
     42    """
     43    Breadcrumb can have methods to customize breadcrumb object, Breadcrumbs
     44    class send to us name and url.
     45    """
     46    def __init__(self,name,url):
     47        # HERE
     48        #
     49        # If I don't use force_unicode, always runs ok, but have problems on
     50        # template with unicode text
     51        self.name = name
     52        self.url = url
     53
     54    def __str__(self):
     55        return self.__unicode__()
     56
     57    def __unicode__(self):
     58        return u"%s,%s" % (self.name,self.url)
     59
     60    def __repr__(self):
     61        return u"Breadcrumb <%s,%s>" % (self.name,self.url)
     62
     63class Breadcrumbs(Singleton):
     64    """
     65    Breadcrumbs maintain a list of breadcrumbs that you can get interating with
     66    class or with get_breadcrumbs().
     67    """
     68    def _1st_init(self,*args,**kwargs):
     69        """
     70        singleton function that start some variables
     71        """
     72        self._clean()
     73        self.__init__(*args,**kwargs)
     74
     75    def __call__(self,*args,**kwargs):
     76        if not len(args) and not len(kwargs):
     77            return self
     78        return self.__init__(*args,**kwargs)
     79
     80    def _clean(self):
     81        self.__bds = []
     82        self.__autohome=settings.BREADCRUMBS_AUTO_HOME
     83        self.__urls =[]
     84
     85    def __init__(self,*args,**kwargs):
     86        """
     87        Call validate and if ok, call fill bd
     88        """
     89        if settings.BREADCRUMBS:
     90
     91            # fill home if settings.BREADCRUMBS_AUTO_HOME is True
     92            if self.__autohome and len(self.__bds) == 0:
     93                self.__fill_bds( ( _("Home"), u"/" ) )
     94
     95            # match Breadcrumbs( 'name', 'url' )
     96            if len(args) == 2 and type(args[0]) not in (list,tuple):
     97                if(self.__validate(args,0)):
     98                    self.__fill_bds( args )
     99            # match ( ( 'name', 'url'), ..) and samething with list
     100            elif len(args) == 1 and type(args[0]) in (list,tuple) \
     101                    and len(args[0]) > 0:
     102                for i,arg in enumerate(args[0]):
     103                    if self.__validate(arg,i):
     104                        self.__fill_bds( arg )
     105            # try to ( obj1, obj2, ... ) and samething with list
     106            else:
     107                for i,arg in enumerate(args):
     108                    if(self.__validate(arg,i)):
     109                        self.__fill_bds( arg )
     110
     111    def __validate(self,obj,index):
     112        """
     113        check for object type and return a string as name for each item of a
     114        list or tuple with items, if error was found raise
     115        BreadcrumbsInvalidFormat
     116        """
     117        # for list or tuple
     118        if type(obj) in (list,tuple):
     119            if len(obj) == 2:
     120                if (not obj[0] and not obj[1]) or \
     121                ( type(obj[0]) not in (str,unicode) and \
     122                  type(obj[1]) not in (str,unicode)):
     123                    raise BreadcrumbsInvalidFormat(u"Invalid format for \
     124                        breadcrumb %s in %s" % (index,type(obj).__name__))
     125            if len(obj) != 2:
     126                raise BreadcrumbsInvalidFormat(
     127                    u"Wrong itens number in breadcrumb %s in %s. \
     128                    You need to send as example (name,url)" % \
     129                    (index,type(obj).__name__)
     130                )
     131        # for objects
     132        elif not hasattr(obj,'name') and not hasattr(obj,'url'):
     133            raise BreadcrumbsInvalidFormat(u"You need to use a tuple like"+ \
     134                " (name,url) or object with name and url attributes for" + \
     135                "breadcrumb.")
     136        return True
     137
     138    def __fill_bds(self,bd):
     139        """
     140        simple interface to add Breadcrumb to bds
     141        """
     142        if hasattr(bd,'name') and hasattr(bd,'url'):
     143            bd = Breadcrumb(bd.name,bd.url)
     144        else:
     145            bd = Breadcrumb(*bd)
     146        if bd.url not in self.__urls:
     147            self.__bds.append(bd)
     148            self.__urls.append(bd.url)
     149
     150    def __iter__(self):
     151        return iter(self.__bds)
     152
     153    def __getitem__(self,key):
     154        return self.__bds[key]
     155
     156    def __repr__(self):
     157        return self.__unicode__()
     158
     159    def __str__(self):
     160        return self.__unicode__()
     161
     162    def __unicode__(self):
     163        return u"Breadcrumbs <%s>" % u", ".join([mark_safe(item.name) for item in \
     164            self[:10]] + [u' ...'])
     165
     166    def all(self):
     167        return self.__bds
  • django/contrib/breadcrumbs/middleware.py

     
     1from breadcrumbs import Breadcrumbs
     2
     3class BreadcrumbsMiddleware(object):
     4
     5    def process_request(self,request):
     6        request.breadcrumbs = Breadcrumbs()
     7        request.breadcrumbs._clean()
  • django/contrib/breadcrumbs/__init__.py

     
     1from breadcrumbs import Breadcrumb
  • django/contrib/breadcrumbs/utils.py

     
     1from breadcrumbs import Breadcrumbs,BreadcrumbsNotSet
     2from django.contrib.flatpages.models import FlatPage
     3from django.http import Http404
     4
     5def breadcrumbs_for_flatpages(request,flatpage):
     6
     7    if not hasattr(request,'breadcrumbs') or \
     8        not isinstance(request.breadcrumbs,Breadcrumbs):
     9        raise BreadcrumbNotSet(u"You need to setup breadcrumbs to use this " + \
     10                "function.")
     11
     12    if not isinstance(flatpage,FlatPage) or \
     13        not hasattr(flatpage,'id'):
     14        raise TypeError(u"flatpage argument isn't a FlatPage instance or " + \
     15            "not have id.")
     16
     17    paths = []
     18    for part in request.path_info.split(u"/"):
     19        # When split we have u"" for slashes
     20        if len(part) == 0:
     21            continue
     22        # Add slash again
     23        if not part.startswith(u"/"):
     24            part = u"/"+part
     25        if not part.endswith(u"/"):
     26            part = part+u"/"
     27        # If we have something on paths, url for flatpage is composed of what we
     28        # have in path + part. Note that strins in path not have last slash, but
     29        # part have.
     30        if len(paths) > 0:
     31            url = u"".join(paths+[part])
     32        else:
     33            url = part
     34        # if is same url we don't hit database again
     35        # else, get page from FlatPage. If page doesn't exist, we allow raise
     36        # 404 because it is a url design problem, not flatpages or breadcrumbs
     37        # problem.
     38        if url == flatpage.url:
     39            request.breadcrumbs(flatpage.title,flatpage.url)
     40        else:
     41            try:
     42                f = FlatPage.objects.get(url=url)
     43            except FlatPage.DoesNotExist:
     44                raise Http404
     45            else:
     46                request.breadcrumbs(f.title,f.url)
     47        # add last part of path in paths with one slash
     48        paths.append(u"/"+url[1:-1].rpartition(u"/")[-1])
     49
  • django/contrib/breadcrumbs/tests.py

     
     1# run this script on your shell
     2from django.contrib.breadcrumbs import Breadcrumbs
     3
     4bds = Breadcrumbs()
     5
     6# fill one per time
     7for i in range(5):
     8    bds( 'name%s' % i,'url%s' % i  )
     9
     10# create a simple class to emulate one object with name and url
     11class emulatedobj(object):
     12    def __init__(self,*args):
     13        self.name = args[0]
     14        self.url = args[1]
     15
     16# add 10 objects
     17bds( [ emulatedobj('name %s' % (i+10), 'url %s' % (i+10)) for i in range(10) ] )
     18
     19# print all
     20for bd in bds:
     21    print bd.name,bd.url
  • django/contrib/auth/views.py

     
    1414from django.contrib.auth.models import User
    1515from django.views.decorators.cache import never_cache
    1616
    17 def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
     17def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME, form_object=AuthenticationForm):
    1818    "Displays the login form and handles the login action."
    1919    redirect_to = request.REQUEST.get(redirect_field_name, '')
    2020    if request.method == "POST":
    21         form = AuthenticationForm(data=request.POST)
     21        form = form_object(data=request.POST)
    2222        if form.is_valid():
    2323            # Light security check -- make sure redirect_to isn't garbage.
    2424            if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
     
    2929                request.session.delete_test_cookie()
    3030            return HttpResponseRedirect(redirect_to)
    3131    else:
    32         form = AuthenticationForm(request)
     32        form = form_object(request)
    3333    request.session.set_test_cookie()
    3434    if Site._meta.installed:
    3535        current_site = Site.objects.get_current()
  • django/contrib/flatpages/views.py

     
    55from django.conf import settings
    66from django.core.xheaders import populate_xheaders
    77from django.utils.safestring import mark_safe
     8from django.contrib.breadcrumbs.utils import breadcrumbs_for_flatpages
    89
    910DEFAULT_TEMPLATE = 'flatpages/default.html'
    1011
     
    2930    if f.registration_required and not request.user.is_authenticated():
    3031        from django.contrib.auth.views import redirect_to_login
    3132        return redirect_to_login(request.path)
     33    # if user enabled contrib.breadcrumbs add page to breadcrumbs
     34    if settings.BREADCRUMBS:
     35        breadcrumbs_for_flatpages(request,f)
    3236    if f.template_name:
    3337        t = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
    3438    else:
Back to Top