# -*- coding: utf-8 -*-
# This file is part of Shoop.
#
# Copyright (c) 2012-2016, Shoop Ltd. All rights reserved.
#
# This source code is licensed under the AGPLv3 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals
import hashlib
import six
from django.core.urlresolvers import reverse
from django.utils.encoding import force_bytes, force_text
[docs]class AdminModule(object):
name = "_Base_"
# A menu entry to represent this module in breadcrumbs
breadcrumbs_menu_entry = None
[docs] def get_urls(self):
"""
:rtype: list[django.core.urlresolvers.RegexURLPattern]
"""
return ()
[docs] def get_search_results(self, request, query):
"""
:rtype: list[shoop.admin.base.SearchResult]
"""
return ()
[docs] def get_dashboard_blocks(self, request):
"""
:rtype: list[shoop.admin.dashboard.DashboardBlock]
"""
return ()
[docs] def get_required_permissions(self):
"""
:rtype: list[str]
"""
return ()
[docs] def get_notifications(self, request):
"""
:rtype: list[shoop.admin.base.Notification]
"""
return ()
[docs] def get_activity(self, request, cutoff):
"""
:param cutoff: Cutoff datetime
:type cutoff: datetime.datetime
:param request: Request
:type request: django.http.request.HttpRequest
:return: list[shoop.admin.base.Activity]
"""
return ()
[docs] def get_model_url(self, object, kind):
"""
Retrieve an admin URL for the given object of the kind `kind`.
A falsy value must be returned if the module does not know
how to reverse the given object.
:param object: A object instance (or object class).
:type object: django.db.models.Model
:param kind: URL kind. Currently "detail", "list" or "new".
:type kind: str
:return: The reversed URL or none.
:rtype: str|None
"""
return None
[docs]class Resolvable(object):
_url = "" # Set on instance level.
@property
def url(self):
"""
Resolve this object's `_url` to an actual URL.
:return: URL or no URL.
:rtype: str|None
"""
url = self._url
if not url:
return None
if isinstance(url, tuple):
(viewname, args, kwargs) = url
return reverse(viewname, args=args, kwargs=kwargs)
if isinstance(url, six.string_types):
if url.startswith("http") or "/" in url:
return url
return reverse(url)
raise TypeError("Can't real_url: %r" % url)
@property
def original_url(self):
return self._url
[docs]class SearchResult(Resolvable):
def __init__(self, text, url, icon=None, category=None, is_action=False, relevance=100, target=None):
self.text = text
self._url = url
self.icon = icon
self.category = category
self.is_action = bool(is_action)
self.relevance = relevance
self.target = target
[docs] def to_json(self):
return {
"text": force_text(self.text),
"url": self.url,
"icon": self.icon,
"category": force_text(self.category),
"isAction": self.is_action,
"relevance": self.relevance,
"target": self.target,
}
[docs]class Notification(Resolvable):
KINDS = ("info", "success", "warning", "danger")
def __init__(self, text, title=None, url=None, kind="info", dismissal_url=None, datetime=None):
"""
:param text: The notification's text.
:type text: str
:param title: An optional title for the notification.
:type title: str|None
:param url: The optional main URL for the notification.
:type url: str|None
:param kind: The kind of the notification (see KINDS)
:type kind: str
:param dismissal_url: An optional dismissal URL for the notification.
The admin framework will add a button that will
cause an AJAX post into this URL.
:type dismissal_url: str|None
:param datetime: An optional date+time for this notification.
:type datetime: datetime
"""
self.title = title
self.text = text
self._url = url
self.dismissal_url = dismissal_url
self.kind = kind
self.datetime = datetime
bits = [force_text(v) for (k, v) in sorted(vars(self).items())]
self.id = hashlib.md5(force_bytes("+".join(bits))).hexdigest()
[docs]class Activity(Resolvable):
def __init__(self, datetime, text, url=None):
self.datetime = datetime
self.text = text
self._url = url
[docs]class OrderSection(object):
"""
Subclass this and add the class to the `admin_order_section` provide list
to show a custom section on the order detail on admin.
`identifier` must be unique
`name` the section caption
`icon` the section icon
`template` the section template file
`extra_js` the section extra javascript template file,
set a file which contains js code inside a <script> tag
`order` the order
"""
identifier = ""
name = ""
icon = ""
template = ""
extra_js = ""
order = 0
@staticmethod
[docs] def visible_for_order(order):
"""
Returns whether this sections must be visible while editing the `order`
:type order: shoop.core.models.Order
:return whether this section must be shown in order section list
:rtype: bool
"""
raise False
@staticmethod
[docs] def get_context_data(order):
"""
Returns additional information to be used in the template
To fetch this data in the template, just access it through `OrderSection_identifier.data`
:type order: shoop.core.models.Order
:return additional context data
:rtype: object|None
"""
return None