1
2
3
4 """Module used within the queue daemon for keeping track of confirmation codes."""
5 import random
6 import string
7 import logging
8 import threading
9 from datetime import datetime
10 from config import config
11
12 -class ConfirmationEntry(object):
13 - def __init__(self, request):
14 self.timestamp = datetime.now()
15 self.expiryTime = datetime.now() + config.confirmTimeout
16 self.request = request
17
19 return datetime.now() >= self.expiryTime
20
23 """Confirmation code map (thread safe).
24
25 Essentially this is a wrapped hash from code string -> request with some
26 helper methods to expire old confirmation entries.
27 """
29 self.codeToRequest = {}
30 self.codeLength = 16
31 self.lock = threading.RLock()
32
34 return [(code,c.request) for code,c in self.codeToRequest.iteritems()]
35
37 with self.lock:
38 if code in self.codeToRequest:
39 raise ExistingCodeError("%s already exists in map", code)
40
41 self.codeToRequest[code] = ConfirmationEntry(request)
42
49
51 with self.lock:
52 if code in self.codeToRequest:
53 request = self.codeToRequest[code].request
54 del self.codeToRequest[code]
55 return request
56 else:
57 raise KeyError("Code does not exist")
58
60 """Expire old confirmations - meant to be called at a regular rate."""
61
62 with self.lock:
63 delKeys = [k for (k,v) in self.codeToRequest.iteritems() if v.expired()]
64 if len(delKeys) > 0:
65 logging.info("Expiring %d confirmations" % (len(delKeys)))
66 for k in delKeys:
67 del self.codeToRequest[k]
68
70 return "".join(random.choice(string.letters + string.digits)\
71 for i in xrange(self.codeLength))
72