Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

factory.py 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import zlib
  2. from django.conf import settings
  3. from oscar.core.loading import import_module
  4. import_module('basket.models', ['Basket', 'Line'], locals())
  5. import_module('offer.utils', ['Applicator'], locals())
  6. # Basket settings
  7. COOKIE_KEY_OPEN_BASKET = settings.OSCAR_BASKET_COOKIE_OPEN
  8. COOKIE_KEY_SAVED_BASKET = settings.OSCAR_BASKET_COOKIE_SAVED
  9. COOKIE_LIFETIME = settings.OSCAR_BASKET_COOKIE_LIFETIME
  10. class BasketFactory(object):
  11. u"""Factory object for loading baskets."""
  12. def get_or_create_open_basket(self, request, response):
  13. u"""Loads or creates a normal OPEN basket for the current user (anonymous
  14. or not).
  15. """
  16. return self._get_or_create_cookie_basket(request, response,
  17. COOKIE_KEY_OPEN_BASKET, Basket.open)
  18. def get_or_create_saved_basket(self, request, response):
  19. u"""Loads or creates a "save-for-later" basket for the current user"""
  20. return self._get_or_create_cookie_basket(request, response,
  21. COOKIE_KEY_SAVED_BASKET, Basket.saved)
  22. def get_open_basket(self, request):
  23. u"""Returns the basket for the current user"""
  24. return self._get_basket(request, None, COOKIE_KEY_OPEN_BASKET, Basket.open)
  25. def get_saved_basket(self, request, response):
  26. u"""Returns the saved basket for the current user"""
  27. return self._get_basket(request, response, COOKIE_KEY_SAVED_BASKET, Basket.saved)
  28. # Utility methods
  29. def _get_or_create_cookie_basket(self, request, response, cookie_key, manager):
  30. u"""
  31. Loads or creates a basket for the current user. Any offers are also
  32. applied to the basket before it is returned.
  33. """
  34. anon_basket = self._get_cookie_basket(request, response, cookie_key, manager)
  35. if request.user.is_authenticated():
  36. basket, created = manager.get_or_create(owner=request.user)
  37. if anon_basket:
  38. # If signed in user also has a cookie basket, we merge them and
  39. # delete the cookies
  40. basket.merge(anon_basket)
  41. response.delete_cookie(cookie_key)
  42. elif not anon_basket:
  43. # No valid basket found for an unauthenticated user so we create a
  44. # new one and store the id and hash in a cookie.
  45. basket = manager.create()
  46. cookie = "%s_%s" % (basket.id, self._get_basket_hash(basket.id))
  47. response.set_cookie(cookie_key, cookie, max_age=COOKIE_LIFETIME, httponly=True)
  48. else:
  49. # Only the cookie basket found - return it
  50. basket = anon_basket
  51. self._apply_offers_to_basket(request, basket)
  52. return basket
  53. def _apply_offers_to_basket(self, request, basket):
  54. Applicator().apply(request, basket)
  55. def _get_basket(self, request, response, cookie_key, manager):
  56. u"""Returns a basket object given a cookie key and manager."""
  57. b = None
  58. if request.user.is_authenticated():
  59. try:
  60. b = manager.get(owner=request.user)
  61. except Basket.DoesNotExist:
  62. pass
  63. else:
  64. b = self._get_cookie_basket(request, response, cookie_key, manager)
  65. if b:
  66. self._apply_offers_to_basket(request, b)
  67. return b
  68. def _get_cookie_basket(self, request, response, cookie_key, manager):
  69. u"""Returns a basket based on the cookie key given."""
  70. b = None
  71. # If user is anonymous, their basket ID (if they have one) will be
  72. # stored in a cookie together with a hash which verifies it and prevents
  73. # it from being spoofed.
  74. if cookie_key in request.COOKIES:
  75. basket_id, basket_hash = request.COOKIES[cookie_key].split("_")
  76. if basket_hash == self._get_basket_hash(basket_id):
  77. try:
  78. b = manager.get(pk=basket_id, owner=None)
  79. except Basket.DoesNotExist:
  80. b = None
  81. elif response:
  82. # Not all methods are able to pass the response so this doesn't
  83. # always happen.
  84. response.delete_cookie(cookie_key)
  85. return b
  86. def _get_basket_hash(self, id):
  87. u"""
  88. Create a hash of the basket ID using the SECRET_KEY
  89. variable defined in settings.py as a salt.
  90. """
  91. return str(zlib.crc32(str(id)+settings.SECRET_KEY))