
    &gf                     .   d Z ddlmZ 	 ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ  G d
 de      Z G d de      Z G d de      Z G d dee      Z G d dee      Z G d de      Z G d de      Zy# e	$ r ddl
mZ ddlmZ Y }w xY w)zA
Module where admin tools dashboard modules classes are defined.
    )apps)reverse)gettext_lazy)ugettext_lazy)flatatt)is_iterable)capfirst)AppListElementMixinuniquifyc                   d    e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZddZd Zd Zd	 Zd
 Zy)DashboardModulea  
    Base class for all dashboard modules.
    Dashboard modules have the following properties:

    ``enabled``
        Boolean that determines whether the module should be enabled in
        the dashboard by default or not. Default value: ``True``.

    ``draggable``
        Boolean that determines whether the module can be draggable or not.
        Draggable modules can be re-arranged by users. Default value: ``True``.

    ``collapsible``
        Boolean that determines whether the module is collapsible, this
        allows users to show/hide module content. Default: ``True``.

    ``deletable``
        Boolean that determines whether the module can be removed from the
        dashboard by users or not. Default: ``True``.

    ``title``
        String that contains the module title, make sure you use the django
        gettext functions if your application is multilingual.
        Default value: ''.

    ``title_url``
        String that contains the module title URL. If given the module
        title will be a link to this URL. Default value: ``None``.

    ``css_classes``
        A list of css classes to be added to the module ``div`` class
        attribute. Default value: ``None``.

    ``pre_content``
        Text or HTML content to display above the module content.
        Default value: ``None``.

    ``content``
        The module text or HTML content. Default value: ``None``.

    ``post_content``
        Text or HTML content to display under the module content.
        Default value: ``None``.

    ``template``
        The template to use to render the module.
        Default value: 'admin_tools/dashboard/module.html'.
    z!admin_tools/dashboard/module.htmlT Nc                     ||| _         |D ])  }t        | j                  |      st        | |||          + | j                  xs g | _        | j
                  xs g | _        d| _        y )NF)titlehasattr	__class__setattrchildrencss_classes_initialized)selfr   kwargskeys       V/var/www/html/djangosite/lib/python3.12/site-packages/admin_tools/dashboard/modules.py__init__zDashboardModule.__init__U   si    DJ 	0Ct~~s+c6#;/	0 +++1r!    c                      y)af  
        Like for the :class:`~admin_tools.dashboard.Dashboard` class, dashboard
        modules have a ``init_with_context`` method that is called with a
        ``django.template.RequestContext`` instance as unique argument.

        This gives you enough flexibility to build complex modules, for
        example, let's build a "history" dashboard module, that will list the
        last ten visited pages::

            from admin_tools.dashboard import modules

            class HistoryDashboardModule(modules.LinkList):
                title = 'History'

                def init_with_context(self, context):
                    request = context['request']
                    # we use sessions to store the visited pages stack
                    history = request.session.get('history', [])
                    for item in history:
                        self.children.append(item)
                    # add the current page to the history
                    history.insert(0, {
                        'title': context['title'],
                        'url': request.META['PATH_INFO']
                    })
                    if len(history) > 10:
                        history = history[:10]
                    request.session['history'] = history

        Here's a screenshot of our history item:

        .. image:: images/history_dashboard_module.png
        N )r   contexts     r   init_with_contextz!DashboardModule.init_with_contextb   s    D 	r   c                 r    | j                   du xr( | j                  du xr t        | j                        dk(  S )a  
        Return True if the module has no content and False otherwise.

        >>> mod = DashboardModule()
        >>> mod.is_empty()
        True
        >>> mod.pre_content = 'foo'
        >>> mod.is_empty()
        False
        >>> mod.pre_content = None
        >>> mod.is_empty()
        True
        >>> mod.children.append('foo')
        >>> mod.is_empty()
        False
        >>> mod.children = []
        >>> mod.is_empty()
        True
        Nr   )pre_contentpost_contentlenr   r   s    r   is_emptyzDashboardModule.is_empty   s@    ( 4' $%$!#	$r   c                 0   dg}| j                   s|j                  d       | j                  r|j                  d       | j                  r|j                  d       | j                  r|j                  d       || j
                  z  }dj                  |      S )aU  
        Return a string containing the css classes for the module.

        >>> mod = DashboardModule(enabled=False, draggable=True,
        ...                       collapsible=True, deletable=True)
        >>> mod.render_css_classes()
        'dashboard-module disabled draggable collapsible deletable'
        >>> mod.css_classes.append('foo')
        >>> mod.render_css_classes()
        'dashboard-module disabled draggable collapsible deletable foo'
        >>> mod.enabled = True
        >>> mod.render_css_classes()
        'dashboard-module draggable collapsible deletable foo'
        zdashboard-moduledisabled	draggablecollapsible	deletable )enabledappendr)   r*   r+   r   join)r   rets     r   render_css_classesz"DashboardModule.render_css_classes   sx     ""||JJz">>JJ{#JJ}%>>JJ{#txx}r   c                      y Nr   r%   s    r   _prepare_childrenz!DashboardModule._prepare_children   s    r   r3   )__name__
__module____qualname____doc__templater-   r)   r*   r+   
show_titler   	title_urlr   r"   r#   r   idr   r    r&   r1   r4   r   r   r   r   r      se    /b 3HGIKIJEIKKLH	B""H$06r   r   c                   :     e Zd ZdZdZdZdZd Z fdZd Z	 xZ
S )Groupa  
    Represents a group of modules, the group can be displayed in tabs,
    accordion, or just stacked (default).
    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.Group`
    has two extra properties:

    ``display``
        A string determining how the group should be rendered, this can be one
        of the following values: 'tabs' (default), 'accordion' or 'stacked'.

    ``force_show_title``
        Default behaviour for Group module is to force children to always show
        the title if Group has ``display`` = ``stacked``. If this flag is set
        to ``False``, children title is shown according to their``show_title``
        property. Note that in this case is children responsibility to have
        meaningful content if no title is shown.

    Here's an example of modules group::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)
                self.children.append(modules.Group(
                    title="My group",
                    display="tabs",
                    children=[
                        modules.AppList(
                            title='Administration',
                            models=('django.contrib.*',)
                        ),
                        modules.AppList(
                            title='Applications',
                            exclude=('django.contrib.*',)
                        )
                    ]
                ))

    The screenshot of what this code produces:

    .. image:: images/dashboard_module_group.png
    Tz(admin_tools/dashboard/modules/group.htmltabsc                     | j                   ry | j                  D ]H  }d|_        d|_        d|_        | j
                  r| j                  dk(  |_        |j                  |       J d| _         y )NFstackedT)	r   r   r*   r)   r+   force_show_titledisplayr:   r    )r   r   modules      r   r    zGroup.init_with_context   sm    mm 	.F "'F$F$F$$%)\\Y%>!$$W-	. !r   c                 r    t         t        |          ry| j                  D ]  }|j                         r y y)ab  
        A group of modules is considered empty if it has no children or if
        all its children are empty.

        >>> from admin_tools.dashboard.modules import DashboardModule, LinkList
        >>> mod = Group()
        >>> mod.is_empty()
        True
        >>> mod.children.append(DashboardModule())
        >>> mod.is_empty()
        True
        >>> mod.children.append(LinkList('links', children=[
        ...    {'title': 'example1', 'url': 'http://example.com'},
        ...    {'title': 'example2', 'url': 'http://example.com'},
        ... ]))
        >>> mod.is_empty()
        False
        TF)superr>   r&   r   )r   childr   s     r   r&   zGroup.is_empty   s:    & &(]] 	E>>#	 r   c                     t               }t        | j                        D ]H  \  }}| j                  d|j                  xs |dz   }t	        ||      |_        |j                          J y )N_   )set	enumerater   r<   r   r4   )r   seenr<   rD   proposed_ids        r   r4   zGroup._prepare_children  s_     u#DMM2 	'JB%)WWfii.?2a4.?@K d3FI$$&	'r   )r5   r6   r7   r8   rB   r9   rC   r    r&   r4   __classcell__r   s   @r   r>   r>      s*    +Z 9HG!4'r   r>   c                   .    e Zd ZdZ ed      ZdZdZd Zy)LinkLista  
    A module that displays a list of links.
    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.LinkList` takes
    an extra keyword argument:

    ``layout``
        The layout of the list, possible values are ``stacked`` and ``inline``.
        The default value is ``stacked``.

    Link list modules children are simple python dictionaries that can have the
    following keys:

    ``title``
        The link title.

    ``url``
        The link URL.

    ``external``
        Boolean that indicates whether the link is an external one or not.

    ``description``
        A string describing the link, it will be the ``title`` attribute of
        the html ``a`` tag.

    ``attrs``
        Hash comprising attributes of the html ``a`` tag.

    Children can also be iterables (lists or tuples) of length 2, 3, 4 or 5.

    Here's a small example of building a link list module::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)

                self.children.append(modules.LinkList(
                    layout='inline',
                    children=(
                        {
                            'title': 'Python website',
                            'url': 'http://www.python.org',
                            'external': True,
                            'description': 'Python language rocks !',
                            'attrs': {'target': '_blank'},
                        },
                        ['Django', 'http://www.djangoproject.com', True],
                        ['Some internal link', '/some/internal/link/'],
                    )
                ))

    The screenshot of what this code produces:

    .. image:: images/linklist_dashboard_module.png
    Linksz,admin_tools/dashboard/modules/link_list.htmlrA   c                    | j                   ry g }| j                  D ]  }t        |t        t        f      rO|d   |d   d}t        |      dk\  r|d   |d<   t        |      dk\  r|d   |d<   t        |      d	k\  r|d   |d
<   |}d
|vri |d
<   |d   |d
   d<   |j                  dd      r|d   |d
   d<   |j                  dd      rJdj                  dg|d
   j                  dd      j                         z         j                         |d
   d<   t        |d
         |d
<   |j                  |        || _        d| _         y )Nr   rJ   )r   url      external   description   attrsrU   hrefr   r   Fr,   zexternal-linkclassT)r   r   
isinstancetuplelistr$   getr/   splitstripr   r.   )r   r   new_childrenlink	link_dicts        r   r    zLinkList.init_with_contexta  sa   MM 	&D$/&*1gd1g>	t9>,0GIj)t9>/3AwIm,t9>)-aIg& d" "W$(KDM&!xxr*)-m)<Wg&xx
E*),$%W(9(9'2(F(L(L(NN*%' Wg& $DM2DM%)	&* % r   N)	r5   r6   r7   r8   rI   r   r9   layoutr    r   r   r   rR   rR   !  s"    9v gJE=HF!r   rR   c                   N     e Zd ZdZ ed      ZdZdZdZdZ	dZ
d fd	Zd Z xZS )AppLista  
    Module that lists installed apps and their models.
    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.AppList`
    has two extra properties:

    ``models``
        A list of models to include, only models whose name (e.g.
        "blog.comments.models.Comment") match one of the strings (e.g.
        "blog.*") in the models list will appear in the dashboard module.

    ``exclude``
        A list of models to exclude, if a model name (e.g.
        "blog.comments.models.Comment") match an element of this list (e.g.
        "blog.comments.*") it won't appear in the dashboard module.

    If no models/exclude list is provided, **all apps** are shown.

    Here's a small example of building an app list module::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)

                # will only list the django.contrib apps
                self.children.append(modules.AppList(
                    title='Administration',
                    models=('django.contrib.*',)
                ))
                # will list all apps except the django.contrib ones
                self.children.append(modules.AppList(
                    title='Applications',
                    exclude=('django.contrib.*',)
                ))

    The screenshot of what this code produces:

    .. image:: images/applist_dashboard_module.png

    .. note::

        Note that this module takes into account user permissions, for
        example, if a user has no rights to change or add a ``Group``, then
        the django.contrib.auth.Group model line will not be displayed.
    Applicationsz+admin_tools/dashboard/modules/app_list.htmlNc                 
   t        |j                  dg             | _        t        |j                  dg             | _        |j                  dg       | _        |j                  dg       | _        t        t        | "  |fi | y )Nmodelsexcludeinclude_listexclude_list)	ra   poprm   rn   ro   rp   rF   rj   r   )r   r   r   r   s      r   r   zAppList.__init__  sk    6::h34FJJy"56"JJ~r:"JJ~r:gt%e6v6r   c                    | j                   ry | j                  |d         }i }|D ]  \  }}|j                  j                  }||vr6t	        j
                  |      j                  | j                  ||      g d||<   i }|j                  j                  |d<   |d   s|j                  dd      r| j                  ||      |d<   |d   r| j                  ||      |d	<   ||   d
   j                  |        t        |j                               D ]9  }||   d
   j                  d        | j                   j                  ||          ; d| _         y )Nrequest)r   rU   rm   r   changeviewF
change_urladdadd_urlrm   c                     | d   S )Nr   r   )xs    r   <lambda>z+AppList.init_with_context.<locals>.<lambda>  s
    1W: r   )r   T)r   _visible_models_meta	app_labeldjango_appsget_app_configverbose_name_get_admin_app_list_urlverbose_name_pluralrb   _get_admin_change_url_get_admin_add_urlr.   sortedkeyssortr   )	r   r   itemsr   modelpermsr~   
model_dictapps	            r   r    zAppList.init_with_context  s^   $$WY%78! 	9LE5--I$ $229=JJ77wG 	#Y J"'++"A"AJwX%))FE":+/+E+E,
<( U|(,(?(?w(O
9%OH%,,Z8%	9( $))+& 	,CIh$$)=$>MM  c+	, !r   r3   )r5   r6   r7   r8   rI   r   r9   rm   rn   ro   rp   r   r    rO   rP   s   @r   rj   rj   ~  s8    .` nE<HFGLL7!r   rj   c                   >     e Zd ZdZdZdZdZdZdZd fd	Z	d Z
 xZS )	ModelLista	  
    Module that lists a set of models.
    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.ModelList` takes
    two extra arguments:

    ``models``
        A list of models to include, only models whose name (e.g.
        "blog.comments.models.Comment") match one of the strings (e.g.
        "blog.*") in the models list will appear in the dashboard module.

    ``exclude``
        A list of models to exclude, if a model name (e.g.
        "blog.comments.models.Comment") match an element of this list (e.g.
        "blog.comments.*") it won't appear in the dashboard module.

    Here's a small example of building a model list module::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)

                # will only list the django.contrib.auth models
                self.children += [
                    modules.ModelList(
                        title='Authentication',
                        models=['django.contrib.auth.*',]
                    )
                ]

    The screenshot of what this code produces:

    .. image:: images/modellist_dashboard_module.png

    .. note::

        Note that this module takes into account user permissions, for
        example, if a user has no rights to change or add a ``Group``, then
        the django.contrib.auth.Group model line will not be displayed.
    z-admin_tools/dashboard/modules/model_list.htmlNc                    t        |xs g       | _        t        |xs g       | _        |j                  dg       | _        |j                  dg       | _        d|v r|j                  d      | _        ng | _        t        t        | &  |fi | y )Nro   rp   extra)
ra   rm   rn   rq   ro   rp   r   rF   r   r   )r   r   rm   rn   r   r   s        r   r   zModelList.__init__  s|    6<R(GMr*"JJ~r:"JJ~r:fG,DJDJi'88r   c                 $   | j                   ry | j                  |d         }|sy |D ]  \  }}i }|j                  j                  |d<   |d   s|j	                  dd      r| j                  ||      |d<   |d   r| j                  ||      |d<   | j                  j                  |        | j                  rS| j                  D ]D  }i }|d   |d<   |d   |d<   |j	                  dd       |d<   | j                  j                  |       F d	| _         y )
Nrs   r   rt   ru   Frv   rw   rx   T)
r   r|   r}   r   rb   r   r   r   r.   r   )r   r   r   r   r   r   	extra_urls          r   r    zModelList.init_with_context  s&   $$WY%78! 
	-LE5J"'++"A"AJwX%))FE":+/+E+E,
<( U|(,(?(?w(O
9%MM  ,
	- ::!ZZ 1	
&/&8
7#+4\+B
<((1i(F
9%$$Z01 !r   NNN)r5   r6   r7   r8   r9   rm   rn   ro   rp   r   r    rO   rP   s   @r   r   r     s.    )V ?HFGLL	9!r   r   c                   N     e Zd ZdZ ed      ZdZdZdZdZ		 	 d fd	Z
d Z xZS )	RecentActionsa@  
    Module that lists the recent actions for the current user.
    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.RecentActions`
    takes three extra keyword arguments:

    ``include_list``
        A list of contenttypes (e.g. "auth.group" or "sites.site") to include,
        only recent actions that match the given contenttypes will be
        displayed.

    ``exclude_list``
        A list of contenttypes (e.g. "auth.group" or "sites.site") to exclude,
        recent actions that match the given contenttypes will not be
        displayed.

    ``limit``
        The maximum number of children to display. Default value: 10.

    Here's a small example of building a recent actions module::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)

                # will only list the django.contrib apps
                self.children.append(modules.RecentActions(
                    title='Django CMS recent actions',
                    include_list=('cms.page', 'cms.cmsplugin',)
                ))

    The screenshot of what this code produces:

    .. image:: images/recentactions_dashboard_module.png
    zRecent Actionsz1admin_tools/dashboard/modules/recent_actions.html
   Nc                     |xs g | _         |xs g | _        |j                  d|i       t        t        |   |fi | y )Nlimit)ro   rp   updaterF   r   r   )r   r   r   ro   rp   r   r   s         r   r   zRecentActions.__init__c  sB    (.B(.Bw&'mT+E<V<r   c                 N   | j                   ry ddlm ddlm} |d   }fd}|j
                  |j                  j                         }n0|j                  j                  |j
                  j                        }| j                  r!|j                   || j                              }| j                  r!|j                   || j                              }|j                  dd      d | j                   | _        t!        | j                        st#        d	      | _        d
| _         y )Nr   )Q)LogEntryrs   c                     ddl m} d }| D ]K  }t        ||      r |j                        }n	 |j	                  d      \  }} ||      }||}G||z  }M |S #  t        d|z        xY w)Nr   )ContentType)content_type__id.zInvalid contenttype: "%s")content_type__app_labelcontent_type__model)"django.contrib.contenttypes.modelsr   r_   r<   rc   
ValueError)ra   r   qsetcontenttypecurrent_qsetr~   r   r   s          r   get_qsetz1RecentActions.init_with_context.<locals>.get_qsetr  s    FD# /k;7#$knn#EL+6+<+<S+A(	5
 $%09,1$L <'D,.D#/$ K(7+E s   AA,)user__pk__exactcontent_typeuserzNo recent actions.T)r   django.db.modelsr   django.contrib.admin.modelsr   r   objectsallfilterpkro   rp   rn   select_relatedr   r   r$   rI   r"   )r   r   r   rs   r   qsr   s         @r   r    zRecentActions.init_with_contextj  s    &8)$	2 <<!!%%'B!!(((IB8D$5$567BHT%6%678B)).&A+4::N4==! !56D r   )Nr   NN)r5   r6   r7   r8   rI   r   r9   r   ro   rp   r   r    rO   rP   s   @r   r   r   7  s:    $J EBHELL:>"=.!r   r   c                   F     e Zd ZdZ ed      ZdZdZdZd fd	Z	d Z
 xZS )Feeda"  
    Class that represents a feed dashboard module.

    .. important::

        This class uses the
        `Universal Feed Parser module <http://www.feedparser.org/>`_ to parse
        the feeds, so you'll need to install it, all feeds supported by
        FeedParser are thus supported by the Feed

    As well as the :class:`~admin_tools.dashboard.modules.DashboardModule`
    properties, the :class:`~admin_tools.dashboard.modules.Feed` takes two
    extra keyword arguments:

    ``feed_url``
        The URL of the feed.

    ``limit``
        The maximum number of feed children to display. Default value: None,
        which means that all children are displayed.

    Here's a small example of building a recent actions module::

        from admin_tools.dashboard import modules, Dashboard

        class MyDashboard(Dashboard):
            def __init__(self, **kwargs):
                Dashboard.__init__(self, **kwargs)

                # will only list the django.contrib apps
                self.children.append(modules.Feed(
                    title=_('Latest Django News'),
                    feed_url='http://www.djangoproject.com/rss/weblog/',
                    limit=5
                ))

    The screenshot of what this code produces:

    .. image:: images/feed_dashboard_module.png
    zRSS Feedz'admin_tools/dashboard/modules/feed.htmlNc                 V    |j                  ||d       t        t        |   |fi | y )N)feed_urlr   )r   rF   r   r   )r   r   r   r   r   r   s        r   r   zFeed.__init__  s(    8e<=dD"53F3r   c                    | j                   ry dd l}| j                  t        d      	 dd l}|j                  | j                        }| j                  |d   d | j                   }n|d   }|D ]P  }|j                  |_        	  |j                  |j                  dd  |_        | j                  j                  |       R d| _         y # t
        $ r! | j                  j                  ddd       Y y w xY w#  Y VxY w)Nr   z!You must provide a valid feed URLz-You must install the FeedParser python moduleT)r   warningentriesrV   )r   datetimer   r   
feedparserImportErrorr   r.   parser   rf   rU   datepublished_parsed)r   r   r   r   feedr   entrys          r   r    zFeed.init_with_context  s   == @AA	 .::!9oktzz2G9oG 	(E

EI*X]]E,B,B1Q,GH
 MM  '	( !)  	MM  I"  	 s   C
 !C7
'C43C47C;r   )r5   r6   r7   r8   rI   r   r9   r   r   r   r    rO   rP   s   @r   r   r     s-    'R jME8HHE4!r   r   N)r8   django.appsr   r   django.urlsr   django.utils.translationr   rI   r   django.core.urlresolversr   django.forms.utilsr   django.utils.itercompatr   django.utils.textr	   admin_tools.utilsr
   r   objectr   r>   rR   rj   r   r   r   r   r   r   <module>r      s    ,< $: ' / & ;ef ePa'O a'HZ! Z!z\!o2 \!~W!!4 W!ta!O a!HO!? O!a  <0;<s   B   BB