Ticket #13376: messages_expirity_capabilities.1.diff
File messages_expirity_capabilities.1.diff, 36.9 KB (added by , 14 years ago) |
---|
-
contrib/messages/restrictions.py
1 import time as time_provider 2 3 4 class Restriction (object): 5 def __init__(self, name): 6 self.type = name 7 8 def to_remove(self): 9 ''' indicates whether given message should be removed ''' 10 raise NotImplementedError () 11 12 def on_iter (self): 13 ''' called when iterated - defaultly do nothing ''' 14 15 16 class TimeRestriction (Restriction): 17 def __init__(self, seconds): 18 """ 19 seconds - expiration time since now 20 """ 21 Restriction.__init__(self, 'time') 22 created = time_provider.time() 23 self.expires = created + int(seconds) 24 25 def set_expirity_time(self, expiration_time): 26 """ 27 Sets expilcity expiration time 28 """ 29 self.expires = int(expiration_time) 30 31 def to_remove (self): 32 return self.expires < time_provider.time() 33 34 def __eq__(self, other): 35 return self.expires == other.expires 36 37 38 class AmountRestriction (Restriction): 39 def __init__(self, amount): 40 assert int(amount) >= 0 41 Restriction.__init__(self, 'amount') 42 self.can_be_shown = int(amount) 43 44 def on_iter (self): 45 self.can_be_shown -= 1 46 47 def to_remove(self): 48 return int(self.can_be_shown) <= 0 49 50 def __eq__(self, other): 51 return self.can_be_shown == other.can_be_shown 52 -
contrib/messages/api.py
13 13 pass 14 14 15 15 16 def add_message(request, level, message, extra_tags='', fail_silently=False ):16 def add_message(request, level, message, extra_tags='', fail_silently=False, restrictions = []): 17 17 """ 18 18 Attempts to add a message to the request using the 'messages' app, falling 19 19 back to the user's message_set if MessageMiddleware hasn't been enabled. 20 20 """ 21 21 if hasattr(request, '_messages'): 22 return request._messages.add(level, message, extra_tags )22 return request._messages.add(level, message, extra_tags, restrictions = restrictions) 23 23 if hasattr(request, 'user') and request.user.is_authenticated(): 24 24 return request.user.message_set.create(message=message) 25 25 if not fail_silently: -
contrib/messages/tests/restrictions.py
1 from django.test import TestCase 2 from django.contrib.messages import restrictions 3 from django.contrib.messages.restrictions import AmountRestriction, TimeRestriction 4 from django.contrib.messages.tests.time_provider import TestTimeProvider 5 6 restrictions.time_provider = TestTimeProvider () 7 8 class RestrictionsTest(TestCase): 9 def __check_expired(self, amount_restriction, iterations_amount): 10 """ 11 Checks whether after iterations_amount of on_iterate given restriction will become expired 12 But before iterations_amount given amount_restriction must not indicate to_remove 13 """ 14 for i in range(iterations_amount): 15 self.assertFalse(amount_restriction.to_remove()) 16 amount_restriction.on_iter() 17 self.assertTrue(amount_restriction.to_remove()) 18 19 def test_amount_restrictions(self): 20 res = AmountRestriction(4) 21 self.__check_expired(res, 4) 22 23 def test_amount_restrictions_invalid_argument(self): 24 self.assertRaises(AssertionError, AmountRestriction, -1) 25 26 def test_equal(self): 27 self.assertEqual(AmountRestriction(5), AmountRestriction(5)) 28 self.assertFalse(AmountRestriction(1) == AmountRestriction(3)) 29 self.assertEqual(TimeRestriction(2), TimeRestriction(2)) 30 self.assertFalse(TimeRestriction(3) == TimeRestriction(4)) 31 -
contrib/messages/tests/time_provider.py
1 class TestTimeProvider(object): 2 def __init__(self, act_time = 0): 3 self.act_time = act_time 4 def set_act_time(self, act_time): 5 self.act_time = act_time 6 def time(self): 7 return self.act_time 8 def inc_act_time(self): 9 self.act_time += 1 -
contrib/messages/tests/cookie.py
1 1 from django.contrib.messages import constants 2 2 from django.contrib.messages.tests.base import BaseTest 3 from django.contrib.messages.tests.time_provider import TestTimeProvider 4 from django.contrib.messages import restrictions 5 from django.contrib.messages.restrictions import TimeRestriction, AmountRestriction 3 6 from django.contrib.messages.storage.cookie import CookieStorage, \ 4 7 MessageEncoder, MessageDecoder 5 8 from django.contrib.messages.storage.base import Message … … 46 49 def test_get(self): 47 50 storage = self.storage_class(self.get_request()) 48 51 # Set initial data. 49 example_messages = ['test', 'me'] 52 example_messages = [Message(constants.INFO, 'test'), Message(constants.INFO, 'me')] 53 expected_messages = [Message(constants.INFO, 'test', restrictions = [AmountRestriction(0),]),\ 54 Message(constants.INFO, 'me', restrictions = [AmountRestriction(0),])] 50 55 set_cookie_data(storage, example_messages) 51 56 # Test that the message actually contains what we expect. 52 self.assertEqual(list(storage), ex ample_messages)57 self.assertEqual(list(storage), expected_messages) 53 58 54 59 def test_get_bad_cookie(self): 55 60 request = self.get_request() … … 91 96 instances is properly encoded/decoded by the custom JSON 92 97 encoder/decoder classes. 93 98 """ 99 restrictions.time_provider = TestTimeProvider() 100 restrictions.time_provider.set_act_time(0) 94 101 messages = [ 95 102 { 96 103 'message': Message(constants.INFO, 'Test message'), 97 'message_list': [Message(constants.INFO, 'message %s') \ 104 'message_list': [Message(constants.INFO, 'message %s', \ 105 restrictions = [TimeRestriction(5), AmountRestriction(3), TimeRestriction(2), AmountRestriction(10)]) \ 98 106 for x in xrange(5)] + [{'another-message': \ 99 107 Message(constants.ERROR, 'error')}], 100 108 }, … … 104 112 value = encoder.encode(messages) 105 113 decoded_messages = json.loads(value, cls=MessageDecoder) 106 114 self.assertEqual(messages, decoded_messages) 115 116 def transport_storage(self, response, request): 117 request.COOKIES['messages'] = response.cookies['messages'].value 118 -
contrib/messages/tests/base.py
4 4 from django.test import TestCase 5 5 from django.conf import settings 6 6 from django.utils.translation import ugettext_lazy 7 from django.contrib.messages import constants, utils, get_level, set_level 7 from django.contrib.messages import constants, utils, get_level, set_level, restrictions 8 8 from django.contrib.messages.api import MessageFailure 9 from django.contrib.messages.restrictions import AmountRestriction, TimeRestriction 9 10 from django.contrib.messages.storage import default_storage, base 10 11 from django.contrib.messages.storage.base import Message 12 from django.contrib.messages.tests.time_provider import TestTimeProvider 11 13 from django.core.urlresolvers import reverse 12 14 from django.contrib.auth.models import User 13 15 16 restrictions.time_provider= TestTimeProvider() 14 17 18 # TODO: make def read(storage) method that would simulate reading messages from storage 15 19 def add_level_messages(storage): 16 20 """ 17 21 Adds 6 messages from different levels (including a custom one) to a storage … … 92 96 storage._loaded_data = data or [] 93 97 return storage 94 98 99 def read_storage(self, storage): 100 """ 101 Simulates reading all messages from given storage 102 Returns list of read messages 103 """ 104 return list(storage) 105 95 106 def test_add(self): 96 107 storage = self.get_storage() 97 108 self.assertFalse(storage.added_new) … … 167 178 response = self.client.post(add_url, data, follow=True) 168 179 self.assertRedirects(response, show_url) 169 180 self.assertTrue('messages' in response.context) 170 messages = [Message(self.levels[level], msg ) for msg in181 messages = [Message(self.levels[level], msg, restrictions = [AmountRestriction(0),]) for msg in 171 182 data['messages']] 172 183 self.assertEqual(list(response.context['messages']), messages) 173 184 for msg in data['messages']: … … 180 191 """ 181 192 settings.MESSAGE_LEVEL = constants.DEBUG 182 193 data = { 183 'messages': [' Test message%d' % x for x in xrange(10)],194 'messages': ['%d' % x for x in xrange(10)], 184 195 } 185 196 show_url = reverse('django.contrib.messages.tests.urls.show') 186 197 messages = [] … … 191 202 args=(level,)) 192 203 self.client.post(add_url, data) 193 204 response = self.client.get(show_url) 205 new_messages = [] 206 for level in ('debug', 'info', 'success', 'warning', 'error'): 207 new_messages.extend([Message(self.levels[level], msg, \ 208 restrictions = [AmountRestriction(0),]) for msg in data['messages']]) 194 209 self.assertTrue('messages' in response.context) 195 self.assertEqual(list(response.context['messages']), messages)210 self.assertEqual(list(response.context['messages']), new_messages) 196 211 for msg in data['messages']: 197 212 self.assertContains(response, msg) 198 213 … … 406 421 # Ensure the level tags constant is put back like we found it. 407 422 self.restore_setting('MESSAGE_TAGS') 408 423 base.LEVEL_TAGS = utils.get_level_tags() 424 425 def test_storing_restrictoins(self): 426 storage = self.get_storage() 427 response = self.get_response() 428 429 get_res = lambda ar1, ar2, tr1, tr2: [AmountRestriction(ar1), AmountRestriction(ar2), TimeRestriction(tr1), TimeRestriction(tr2)] 430 431 restrictions.time_provider.set_act_time(0) 432 storage.add(constants.WARNING, 'First msg', restrictions = get_res(10, 20, 30, 40)) 433 messages = self.__read_messages(storage, response) 434 self.assertEqual(len(messages), 1) 435 rest = messages[0].restrictions 436 for a in (9, 19): 437 self.assertTrue(a in [r.can_be_shown for r in rest if r.type == 'amount']) 438 for t in (30, 40): 439 self.assertTrue(t in [r.expires for r in rest if r.type == 'time']) 440 441 restrictions.time_provider.set_act_time(4) 442 storage = self.get_storage() 443 response = self.get_response() 444 storage.add(constants.WARNING, 'First msg', restrictions = get_res(10, 20, 30, 40)) 445 messages = self.__read_messages(storage, response) 446 rest = messages[0].restrictions 447 for a in (9, 19): 448 self.assertTrue(a in [r.can_be_shown for r in rest if r.type == 'amount']) 449 for t in (34, 44): 450 self.assertTrue(t in [r.expires for r in rest if r.type == 'time']) 451 452 def test_expire_default(self): 453 """ 454 Tests against message expiration in default behaviour (no explicity defined restrictions on expire -> show only once) 455 """ 456 storage = self.get_existing_storage() 457 response = self.get_response() 458 459 list (storage) 460 storage.update(response) 461 462 storing = self.stored_messages_count(storage, response) 463 self.assertEqual(storing, 0) 464 465 def test_expire_after_showing_given_amount_of_times(self): 466 """ 467 Tests against expiring message after beeing shown given amount of times 468 """ 469 storage = self.get_existing_storage() 470 response = self.get_response() 471 472 read_messages = lambda: self.__read_messages(storage, response) 473 474 storage.add(constants.WARNING, 'Third message, should be shown four times', restrictions = [AmountRestriction(4),]) 475 storage.add(constants.ERROR, "Four'th message, should be shown five times", restrictions = [AmountRestriction(5),]) 476 477 478 messages = read_messages () 479 self.assertEqual(len(messages), 4) 480 storing = self.stored_messages_count(storage, response) 481 self.assertEqual(storing, 2) 482 483 484 for i in range(2): 485 messages = read_messages () 486 self.assertEqual(len(messages), 2) 487 storing = self.stored_messages_count(storage, response) 488 self.assertEqual(storing, 2) 489 [self.assertTrue(level in [x.level for x in messages]) for level in (constants.ERROR, constants.WARNING)] 490 491 492 messages = read_messages () 493 self.assertEqual(len(messages), 2) 494 storing = self.stored_messages_count(storage, response) 495 self.assertEqual(storing, 1) 496 497 498 messages = read_messages() 499 self.assertEqual(len(messages), 1) 500 self.assertEqual(messages[0].level, constants.ERROR) 501 storing = self.stored_messages_count(storage, response) 502 self.assertEqual(storing, 0) 503 504 505 messages = read_messages() 506 self.assertEqual(len(messages), 0) 507 storing = self.stored_messages_count(storage, response) 508 self.assertEqual(storing, 0) 509 510 def test_expire_after_time(self): 511 storage = self.get_storage() 512 response = self.get_response() 513 res = restrictions 514 res.time_provider.set_act_time(0) 515 516 storage.add(constants.WARNING, 'Third message, should be shown four times', restrictions = [TimeRestriction(4),]) 517 storage.add(constants.ERROR, "Four'th message, should be shown five times", restrictions = [TimeRestriction(6),]) 518 519 for i in range(10): 520 messages = self.__read_messages(storage, response) 521 self.assertEqual(len(messages), 2) 522 storing = self.stored_messages_count(storage, response) 523 self.assertEqual(storing, 2) 524 525 res.time_provider.set_act_time(5) 526 messages = self.__read_messages(storage, response) 527 self.assertEqual(len(messages), 1) 528 self.assertEqual(messages[0].level, constants.ERROR) 529 storing = self.stored_messages_count(storage, response) 530 self.assertEqual(storing, 1) 531 532 res.time_provider.set_act_time(7) 533 messages = self.__read_messages(storage, response) 534 self.assertEqual(len(messages), 0) 535 storing = self.stored_messages_count(storage, response) 536 self.assertEqual(storing, 0) 537 538 def test_expire_fixed_restrictions(self): 539 """ 540 Check message expirity when defining few sort of restrictions 541 of different kind 542 """ 543 get_storage_and_response = lambda: (self.get_storage(), self.get_response()) 544 storage, response = get_storage_and_response() 545 get_res = lambda ar1, ar2, tr1, tr2: [AmountRestriction(ar1), AmountRestriction(ar2), TimeRestriction(tr1), TimeRestriction(tr2)] 546 547 548 def check_storage(storage, iterations, expected_amount, fnct = None): 549 """ 550 Checks whether given storage would contain expected_amount of messages before each of iterations iterations 551 Performs iterations amount of iterations 552 Calls fnct at the end of each iteration 553 """ 554 for i in range(iterations): #read 2 times 555 messages = self.__read_messages(storage, response) 556 self.assertEqual(len(messages), expected_amount) 557 storing = self.stored_messages_count(storage, response) 558 self.assertEqual(storing, expected_amount) 559 if fnct: fnct() 560 561 # first - expires after amount of showing 562 restrictions.time_provider.set_act_time(0) 563 storage.add(constants.ERROR, "Some message", restrictions = get_res(7, 30, 5, 20)) 564 storage.add(constants.INFO, "another message", restrictions = get_res(3, 10, 4, 11)) 565 check_storage(storage, 2, 2) 566 messages = self.__read_messages(storage, response) # 3 times read 567 self.assertEqual(len(messages), 2) 568 storing = self.stored_messages_count(storage, response) 569 self.assertEqual(storing, 1) 570 check_storage(storage, 3, 1) 571 572 573 storage, response = get_storage_and_response() 574 restrictions.time_provider.set_act_time(0) 575 storage.add(constants.ERROR, "Some message", restrictions = get_res(7, 30, 5, 20)) 576 storage.add(constants.INFO, "another message", restrictions = get_res(3, 10, 4, 11)) 577 restrictions.time_provider.set_act_time(2) 578 check_storage(storage, 2, 2, lambda:restrictions.time_provider.set_act_time(3)) 579 580 # second - expires after amount of time 581 storage, response = get_storage_and_response() 582 restrictions.time_provider.set_act_time(0) 583 storage.add(constants.ERROR, "Some message", restrictions = get_res(10, 30, 5, 20)) 584 storage.add(constants.INFO, "another message", restrictions = get_res(10, 20, 3, 11)) 585 check_storage(storage, 2, 2) 586 restrictions.time_provider.set_act_time(2) 587 check_storage(storage, 2, 2) 588 restrictions.time_provider.set_act_time(4) 589 check_storage(storage, 2, 1) 590 591 def transport_storage(self, response, request): 592 """ 593 Transports storage from response to request 594 This method can be overriden by subclasses 595 """ 596 597 def __read_messages(self, storage, response):#simulate next call to render messages 598 """ 599 Simulates iterating storage in template 600 Returns messages from that iteration that would be returned 601 """ 602 messages = self.read_storage(storage) 603 storage.update(response) 604 self.transport_storage (response, storage.request) 605 storage.used = False 606 storage._queued_messages = [] 607 del storage._loaded_data 608 return messages 609 -
contrib/messages/tests/__init__.py
1 from django.contrib.messages.tests.session import SessionTest 1 2 from django.contrib.messages.tests.cookie import CookieTest 2 3 from django.contrib.messages.tests.fallback import FallbackTest 3 from django.contrib.messages.tests. middleware import MiddlewareTest4 from django.contrib.messages.tests. session import SessionTest4 from django.contrib.messages.tests.restrictions import RestrictionsTest 5 from django.contrib.messages.tests.message import MessageTest 5 6 from django.contrib.messages.tests.user_messages import \ 6 7 UserMessagesTest, LegacyFallbackTest 8 9 from django.contrib.messages.tests.middleware import MiddlewareTest 10 -
contrib/messages/tests/fallback.py
1 1 from django.contrib.messages import constants 2 from django.contrib.messages.storage.base import Message 2 3 from django.contrib.messages.storage.fallback import FallbackStorage, \ 3 4 CookieStorage 4 5 from django.contrib.messages.tests.base import BaseTest 5 6 from django.contrib.messages.tests.cookie import set_cookie_data, \ 6 7 stored_cookie_messages_count 8 from django.contrib.messages.restrictions import AmountRestriction 7 9 from django.contrib.messages.tests.session import set_session_data, \ 8 10 stored_session_messages_count 9 11 … … 44 46 cookie_storage = self.get_cookie_storage(storage) 45 47 46 48 # Set initial cookie data. 47 example_messages = [str(i) for i in range(5)] 49 example_messages = [Message(constants.INFO, str(i)) for i in range(5)] 50 expected_messages = [Message(constants.INFO, str(i), restrictions = [AmountRestriction(0),]) for i in range(5)] 48 51 set_cookie_data(cookie_storage, example_messages) 49 52 50 53 # Overwrite the _get method of the fallback storage to prove it is not … … 52 55 self.get_session_storage(storage)._get = None 53 56 54 57 # Test that the message actually contains what we expect. 55 self.assertEqual(list(storage), ex ample_messages)58 self.assertEqual(list(storage), expected_messages) 56 59 57 60 def test_get_empty(self): 58 61 request = self.get_request() … … 72 75 session_storage = self.get_session_storage(storage) 73 76 74 77 # Set initial cookie and session data. 75 example_messages = [str(i) for i in range(5)] 78 example_messages = [Message(constants.INFO, str(i)) for i in range(5)] 79 expected_messages = [Message(constants.INFO, str(i), restrictions = [AmountRestriction(0),]) for i in range(5)] 76 80 set_cookie_data(cookie_storage, example_messages[:4] + 77 81 [CookieStorage.not_finished]) 78 82 set_session_data(session_storage, example_messages[4:]) 79 83 80 84 # Test that the message actually contains what we expect. 81 self.assertEqual(list(storage), ex ample_messages)85 self.assertEqual(list(storage), expected_messages) 82 86 83 87 def test_get_fallback_only(self): 84 88 request = self.get_request() … … 87 91 session_storage = self.get_session_storage(storage) 88 92 89 93 # Set initial cookie and session data. 90 example_messages = [ str(i) for i in range(5)]94 example_messages = [Message(constants.INFO, str(i)) for i in range(5)] 91 95 set_cookie_data(cookie_storage, [CookieStorage.not_finished], 92 96 encode_empty=True) 93 97 set_session_data(session_storage, example_messages) … … 102 106 session_storage = self.get_session_storage(storage) 103 107 104 108 # Set initial cookie and session data. 105 set_cookie_data(cookie_storage, [ 'cookie', CookieStorage.not_finished])106 set_session_data(session_storage, [ 'session'])109 set_cookie_data(cookie_storage, [Message(constants.INFO, 'cookie'), CookieStorage.not_finished]) 110 set_session_data(session_storage, [Message(constants.INFO, 'session')]) 107 111 108 112 # When updating, previously used but no longer needed backends are 109 113 # flushed. … … 173 177 self.assertEqual(cookie_storing, 0) 174 178 session_storing = self.stored_session_messages_count(storage, response) 175 179 self.assertEqual(session_storing, 1) 180 181 def transport_storage(self, response, request): 182 request.COOKIES['messages'] = response.cookies['messages'].value -
contrib/messages/tests/session.py
1 1 from django.contrib.messages.tests.base import BaseTest 2 2 from django.contrib.messages.storage.session import SessionStorage 3 from django.contrib.messages.storage.base import Message 3 4 4 5 5 6 def set_session_data(storage, messages): … … 32 33 def test_get(self): 33 34 storage = self.storage_class(self.get_request()) 34 35 # Set initial data. 35 example_messages = [ 'test', 'me']36 example_messages = [Message(1, 'test') , Message(1, 'me')] 36 37 set_session_data(storage, example_messages) 37 38 # Test that the message actually contains what we expect. 38 39 self.assertEqual(list(storage), example_messages) -
contrib/messages/tests/message.py
1 from django.test import TestCase 2 from django.contrib.messages.storage.base import Message 3 from django.contrib.messages import restrictions 4 from django.contrib.messages.restrictions import AmountRestriction, TimeRestriction, time_provider 5 from django.contrib.messages.tests.time_provider import TestTimeProvider 6 from django.contrib.messages import constants 7 8 9 class MessageTest(TestCase): 10 def setUp(self): 11 self.tp = restrictions.time_provider = TestTimeProvider () 12 def __check_active(self, msg, iterations): 13 """ 14 Reads msg given amount of iterations, and after each read 15 checks whether before each read message is active 16 """ 17 for i in range(iterations): 18 self.assertTrue(msg.active()) 19 msg.on_iter() 20 self.assertFalse(msg.active()) 21 msg.on_iter() 22 self.assertFalse(msg.active()) 23 24 def test_active_default(self): 25 msg = Message(constants.INFO, "Test message") 26 self.__check_active(msg, 1) 27 28 def test_active_custom_one_amount_restriction(self): 29 msg = Message(constants.INFO, "Test message", restrictions = [AmountRestriction(3),]) 30 self.__check_active(msg, 3) 31 32 def test_active_custom_few_amount_restriction(self): 33 msg = Message(constants.INFO, "Test message", restrictions = [AmountRestriction(x) for x in (2, 3, 5)]) 34 self.__check_active(msg, 2) 35 36 def test_active_custom_one_time_restriction(self): 37 msg = Message(constants.INFO, "Test message", restrictions = [TimeRestriction(3),]) 38 def check_iter(): 39 for i in range(10): # iteration doesn't have direct impact for TimeRestriction 40 self.assertTrue(msg.active()) 41 msg.on_iter() 42 check_iter() 43 self.tp.set_act_time(3) 44 check_iter() 45 self.tp.set_act_time(4) 46 self.assertFalse(msg.active()) 47 48 49 def test_mixed_restrictions(self): 50 get_restrictions = lambda:[TimeRestriction(3), TimeRestriction(5), AmountRestriction(2), AmountRestriction(3)] 51 get_msg = lambda:Message(constants.INFO, "Test message", restrictions = get_restrictions()) 52 53 msg = get_msg() 54 for i in range(2): 55 self.assertTrue(msg.active()) 56 msg.on_iter() 57 self.assertFalse(msg.active()) 58 59 msg = get_msg() 60 self.assertTrue(msg.active()) 61 msg.on_iter() 62 self.assertTrue(msg.active()) 63 self.tp.set_act_time(4) 64 self.assertFalse(msg.active()) 65 for i in range(10): 66 self.assertFalse(msg.active()) 67 msg.on_iter() 68 69 -
contrib/messages/tests/user_messages.py
1 1 from django import http 2 2 from django.contrib.auth.models import User 3 from django.contrib.messages import constants 4 from django.contrib.messages.storage.base import Message 3 5 from django.contrib.messages.storage.user_messages import UserMessagesStorage,\ 4 6 LegacyFallbackStorage 5 7 from django.contrib.messages.tests.cookie import set_cookie_data … … 57 59 storage = self.storage_class(request) 58 60 cookie_storage = self.get_cookie_storage(storage) 59 61 self.user.message_set.create(message='user message') 60 set_cookie_data(cookie_storage, [ 'cookie'])62 set_cookie_data(cookie_storage, [Message(constants.INFO,'cookie')]) 61 63 62 64 # Test that the message actually contains what we expect. 63 65 self.assertEqual(len(storage), 2) 64 66 self.assertEqual(list(storage)[0].message, 'user message') 65 self.assertEqual(list(storage)[1] , 'cookie')67 self.assertEqual(list(storage)[1].message, 'cookie') -
contrib/messages/storage/cookie.py
7 7 from django.utils import simplejson as json 8 8 from django.utils.hashcompat import sha_hmac 9 9 10 from django.contrib.messages.restrictions import AmountRestriction, TimeRestriction 10 11 11 12 class MessageEncoder(json.JSONEncoder): 12 13 """ … … 14 15 """ 15 16 message_key = '__json_message' 16 17 18 def __encode_restriction (self, r): 19 if r.type == 'amount': ret = '%s@%s' % ('a', r.can_be_shown) 20 elif r.type == 'time': ret = '%s@%s' % ('t', r.expires) 21 return ret 22 17 23 def default(self, obj): 18 24 if isinstance(obj, Message): 19 25 message = [self.message_key, obj.level, obj.message] 20 26 if obj.extra_tags: 21 27 message.append(obj.extra_tags) 28 restrictions = [self.__encode_restriction(r) for r in obj.restrictions] 29 message.append (restrictions) 22 30 return message 23 31 return super(MessageEncoder, self).default(obj) 24 32 … … 27 35 """ 28 36 Decodes JSON that includes serialized ``Message`` instances. 29 37 """ 38 def __get_restrictions (self, restrictions): 39 def _get_r(type, value): 40 if type == 'a': return AmountRestriction (value) 41 elif type == 't': 42 ret = TimeRestriction(0) 43 ret.set_expirity_time(value) 44 return ret 45 ret = [] 46 for r in restrictions: 47 rtype, value = r.split('@') 48 added = _get_r (rtype, value) 49 ret.append (added) 50 return ret 51 #return [_get_r(rtype, value) for rtype, value in [r.split('@') for r in restrictions] ] 30 52 53 54 def create_message(self, vars): 55 ''' creates message on the basis of encoded data ''' 56 args = vars[:-1] 57 restrictions = vars[-1] 58 restrictions = self.__get_restrictions (restrictions) 59 return Message(*args, **{'restrictions': restrictions}) 60 31 61 def process_messages(self, obj): 32 62 if isinstance(obj, list) and obj: 33 63 if obj[0] == MessageEncoder.message_key: 34 return Message(*obj[1:])64 return self.create_message (obj[1:]) 35 65 return [self.process_messages(item) for item in obj] 36 66 if isinstance(obj, dict): 37 67 return dict([(key, self.process_messages(value)) … … 136 166 """ 137 167 if not data: 138 168 return None 139 bits = data.split('$', 1) 169 try: 170 bits = data.split('$', 1) 171 except: 172 set_trace () 140 173 if len(bits) == 2: 141 174 hash, value = bits 142 175 if hash == self._hash(value): … … 150 183 # with the data. 151 184 self.used = True 152 185 return None 186 187 def transport_storage(self, response, request): 188 storage.request.COOKIES['messages'] = response.cookies['messages'].value -
contrib/messages/storage/base.py
1 1 from django.conf import settings 2 2 from django.utils.encoding import force_unicode, StrAndUnicode 3 from django.contrib.messages import constants, utils 3 from django.contrib.messages import constants, utils, restrictions as res 4 4 5 5 6 6 LEVEL_TAGS = utils.get_level_tags() 7 7 8 8 9 9 10 class Message(StrAndUnicode): 10 11 """ … … 13 14 or template. 14 15 """ 15 16 16 def __init__(self, level, message, extra_tags=None ):17 def __init__(self, level, message, extra_tags=None, restrictions = []): 17 18 self.level = int(level) 18 19 self.message = message 19 20 self.extra_tags = extra_tags 20 21 21 def _prepare(self): 22 self.restrictions = restrictions or list([res.AmountRestriction(1)]) 23 # if not given any restriction - one show by default 24 25 def _prepare(self): # todo: slef.restrictions = 22 26 """ 23 27 Prepares the message for serialization by forcing the ``message`` 24 28 and ``extra_tags`` to unicode in case they are lazy translations. … … 31 35 32 36 def __eq__(self, other): 33 37 return isinstance(other, Message) and self.level == other.level and \ 34 self.message == other.message 38 self.message == other.message and \ 39 self.restrictions == other.restrictions 35 40 36 41 def __unicode__(self): 37 return force_unicode(self.message) 42 return force_unicode(self.message) + ':' + unicode('CFVB') 38 43 44 39 45 def _get_tags(self): 40 46 label_tag = force_unicode(LEVEL_TAGS.get(self.level, ''), 41 47 strings_only=True) … … 50 56 tags = property(_get_tags) 51 57 52 58 59 def active (self): 60 for r in self.restrictions: 61 if r.to_remove(): return False 62 return True 63 64 65 def on_iter (self): 66 for r in self.restrictions: 67 r.on_iter () 68 69 53 70 class BaseStorage(object): 54 71 """ 55 72 This is the base backend for temporary message storage. … … 60 77 61 78 def __init__(self, request, *args, **kwargs): 62 79 self.request = request 80 self.used = False 63 81 self._queued_messages = [] 64 self.used = False65 82 self.added_new = False 66 83 super(BaseStorage, self).__init__(*args, **kwargs) 67 84 … … 69 86 return len(self._loaded_messages) + len(self._queued_messages) 70 87 71 88 def __iter__(self): 72 self.used = True73 if self._queued_messages:74 self._loaded_messages.extend(self._queued_messages)75 self._queued_messages = []76 return iter(self._loaded_messages)89 if not self.used: 90 self.used = True 91 if self._queued_messages: 92 self._loaded_messages.extend(self._queued_messages) 93 self._queued_messages = [] 77 94 95 active_messages = [x for x in self._loaded_messages if x.active ()] 96 for x in active_messages: 97 x.on_iter () 98 self._queued_messages.extend (active_messages) 99 return iter(self._queued_messages) 100 101 78 102 def __contains__(self, item): 79 103 return item in self._loaded_messages or item in self._queued_messages 80 104 … … 104 128 """ 105 129 raise NotImplementedError() 106 130 131 def filter_store(self, messages, response, *args, **kwargs): 132 ''' stores only active messages from given messages in storage ''' 133 filtered_messages = [x for x in messages if x.active ()] 134 return self._store(filtered_messages, response, *args, **kwargs) 135 136 107 137 def _store(self, messages, response, *args, **kwargs): 108 138 """ 109 139 Stores a list of messages, returning a list of any messages which could … … 130 160 be stored again. Otherwise, only messages added after the last 131 161 iteration will be stored. 132 162 """ 163 # if used or used and added, then _queued_messages contains all messages that should be saved 164 # if added, then save: all messages currently stored and added ones 133 165 self._prepare_messages(self._queued_messages) 134 166 if self.used: 135 return self. _store(self._queued_messages, response)167 return self.filter_store(self._queued_messages, response) 136 168 elif self.added_new: 137 169 messages = self._loaded_messages + self._queued_messages 138 return self. _store(messages, response)170 return self.filter_store(messages, response) 139 171 140 def add(self, level, message, extra_tags='' ):172 def add(self, level, message, extra_tags='', restrictions = []): 141 173 """ 142 174 Queues a message to be stored. 143 175 … … 152 184 return 153 185 # Add the message. 154 186 self.added_new = True 155 message = Message(level, message, extra_tags=extra_tags )187 message = Message(level, message, extra_tags=extra_tags, restrictions = restrictions) 156 188 self._queued_messages.append(message) 157 189 158 190 def _get_level(self): -
contrib/messages/storage/session.py
22 22 """ 23 23 return self.request.session.get(self.session_key), True 24 24 25 def _store(self, messages, response, *args, **kwargs): 25 def _store(self, messages, response, *args, **kwargs): # overrides all messages existing in storage so far 26 26 """ 27 Stores a list of messages to the request's session. 27 Stores a list of messages to the request's session. 28 28 """ 29 29 if messages: 30 30 self.request.session[self.session_key] = messages