class SynchroStore(Persistent): """ Synchro entries storage """ implements(ISynchroStore) def __init__(self): self._entries = OOBTree() self.busy = False def __iter__(self): for entry in self._entries.itervalues(): yield entry def add(self, date, action, props={}): entry = SynchroEntry(date, action, props) self._entries[entry.id] = entry def remove(self, id): del self._entries[id] def get(self, id): return self._entries[id] @iteration_with_status(SYNCHRO_STATUS.PENDING) def pending(self): pass @iteration_with_status(SYNCHRO_STATUS.CURRENT) def current(self): pass @iteration_with_status(SYNCHRO_STATUS.DONE) def done(self): pass @iteration_with_status(SYNCHRO_STATUS.ERROR) def error(self): pass
class DeployedStore(Persistent): """ Deployed entries storage """ implements(IDeployedStore) store_length = 10 def __init__(self): self._entries = OOBTree() self.busy = False def __iter__(self): return reversed([i for i in self._entries.itervalues()]) def add(self, date, user, action, clear, full, status, errmsg=None): entry = DeployedEntry(date, user, action, clear, full, status, errmsg) self._entries[entry.id] = entry if len(self._entries) > self.store_length: del self._entries[self._entries.minKey()] def remove(self, id): del self._entries[id] def get(self, id): return self._entries[id] @iteration_with_status(DEPLOYMENT_STATUS.DONE) def done(self): pass @iteration_with_status(DEPLOYMENT_STATUS.ERROR) def error(self): pass
class fsIndex(object): def __init__(self, data=None): self._data = OOBTree() if data: self.update(data) def __getstate__(self): return dict(state_version=1, _data=[(k, v.toString()) for (k, v) in self._data.iteritems()]) def __setstate__(self, state): version = state.pop("state_version", 0) getattr(self, "_setstate_%s" % version)(state) def _setstate_0(self, state): self.__dict__.clear() self.__dict__.update(state) def _setstate_1(self, state): self._data = OOBTree([(k, fsBucket().fromString(v)) for (k, v) in state["_data"]]) def __getitem__(self, key): return str2num(self._data[key[:6]][key[6:]]) def save(self, pos, fname): with open(fname, "wb") as f: pickler = cPickle.Pickler(f, 1) pickler.fast = True pickler.dump(pos) for k, v in self._data.iteritems(): pickler.dump((k, v.toString())) pickler.dump(None) @classmethod def load(class_, fname): with open(fname, "rb") as f: unpickler = cPickle.Unpickler(f) pos = unpickler.load() if not isinstance(pos, (int, long)): return pos # Old format index = class_() data = index._data while 1: v = unpickler.load() if not v: break k, v = v data[k] = fsBucket().fromString(v) return dict(pos=pos, index=index) def get(self, key, default=None): tree = self._data.get(key[:6], default) if tree is default: return default v = tree.get(key[6:], default) if v is default: return default return str2num(v) def __setitem__(self, key, value): value = num2str(value) treekey = key[:6] tree = self._data.get(treekey) if tree is None: tree = fsBucket() self._data[treekey] = tree tree[key[6:]] = value def __delitem__(self, key): treekey = key[:6] tree = self._data.get(treekey) if tree is None: raise KeyError, key del tree[key[6:]] if not tree: del self._data[treekey] def __len__(self): r = 0 for tree in self._data.itervalues(): r += len(tree) return r def update(self, mapping): for k, v in mapping.items(): self[k] = v def has_key(self, key): v = self.get(key, self) return v is not self def __contains__(self, key): tree = self._data.get(key[:6]) if tree is None: return False v = tree.get(key[6:], None) if v is None: return False return True def clear(self): self._data.clear() def __iter__(self): for prefix, tree in self._data.iteritems(): for suffix in tree: yield prefix + suffix iterkeys = __iter__ def keys(self): return list(self.iterkeys()) def iteritems(self): for prefix, tree in self._data.iteritems(): for suffix, value in tree.iteritems(): yield (prefix + suffix, str2num(value)) def items(self): return list(self.iteritems()) def itervalues(self): for tree in self._data.itervalues(): for value in tree.itervalues(): yield str2num(value) def values(self): return list(self.itervalues()) # Comment below applies for the following minKey and maxKey methods # # Obscure: what if `tree` is actually empty? We're relying here on # that this class doesn't implement __delitem__: once a key gets # into an fsIndex, the only way it can go away is by invoking # clear(). Therefore nothing in _data.values() is ever empty. # # Note that because `tree` is an fsBTree, its minKey()/maxKey() methods are # very efficient. def minKey(self, key=None): if key is None: smallest_prefix = self._data.minKey() else: smallest_prefix = self._data.minKey(key[:6]) tree = self._data[smallest_prefix] assert tree if key is None: smallest_suffix = tree.minKey() else: try: smallest_suffix = tree.minKey(key[6:]) except ValueError: # 'empty tree' (no suffix >= arg) next_prefix = prefix_plus_one(smallest_prefix) smallest_prefix = self._data.minKey(next_prefix) tree = self._data[smallest_prefix] assert tree smallest_suffix = tree.minKey() return smallest_prefix + smallest_suffix def maxKey(self, key=None): if key is None: biggest_prefix = self._data.maxKey() else: biggest_prefix = self._data.maxKey(key[:6]) tree = self._data[biggest_prefix] assert tree if key is None: biggest_suffix = tree.maxKey() else: try: biggest_suffix = tree.maxKey(key[6:]) except ValueError: # 'empty tree' (no suffix <= arg) next_prefix = prefix_minus_one(biggest_prefix) biggest_prefix = self._data.maxKey(next_prefix) tree = self._data[biggest_prefix] assert tree biggest_suffix = tree.maxKey() return biggest_prefix + biggest_suffix
class Subscriptions(SimpleItem): security = ClassSecurityInfo() title = "Meeting registrations" def __init__(self, id): """ """ super(SimpleItem, self).__init__(id) self.id = id self._signups = OOBTree() self._account_subscriptions = OOBTree() security.declarePublic('getMeeting') def getMeeting(self): return self.aq_parent.aq_parent def _validate_signup(self, form): """ """ formdata = {} formerrors = {} keys = ('first_name', 'last_name', 'email', 'organization', 'phone') formdata = dict((key, form.get(key, '')) for key in keys) for key in formdata: if formdata[key] == '': formerrors[key] = 'This field is mandatory' if formerrors == {}: if formdata['email'].count('@') != 1: formerrors['email'] = ('An email address must contain ' 'a single @') if formerrors == {}: formerrors = None return formdata, formerrors def _add_signup(self, formdata): """ """ meeting = self.getMeeting() key = random_key() name = formdata['first_name'] + ' ' + formdata['last_name'] email = formdata['email'] organization = formdata['organization'] phone = formdata['phone'] signup = SignUp(key, name, email, organization, phone) self._signups.insert(key, signup) if meeting.auto_register: self._accept_signup(key) email_sender = self.getMeeting().getEmailSender() email_sender.send_signup_email(signup) if self.REQUEST.AUTHENTICATED_USER.getUserName() == 'Anonymous User': self.REQUEST.SESSION['nymt-current-key'] = key security.declareProtected(view, 'signup') def signup(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') if REQUEST.get('add_users'): return self.subscribe_accounts(REQUEST) if REQUEST.get('add_signup'): formdata, formerrors = self._validate_signup(REQUEST.form) # check Captcha/reCaptcha if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha(recaptcha_response, REQUEST) if captcha_validator: if formerrors is None: formerrors = {} formerrors['captcha'] = captcha_validator else: REQUEST.SESSION['captcha_passed'] = True if formerrors is not None: return self.getFormsTool().getContent( {'here': self, 'formdata': formdata, 'formerrors': formerrors}, 'naaya.content.meeting.subscription_signup') else: self._add_signup(formdata) if self.getMeeting().survey_required: REQUEST.RESPONSE.redirect( self.getMeeting().absolute_url()) else: REQUEST.RESPONSE.redirect(self.absolute_url() + '/signup_successful') # check Captcha/reCaptcha also for searching users captcha_validator = None if (REQUEST.get('search_user') or REQUEST.get('search_user_with_role')): if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha(recaptcha_response, REQUEST) if not captcha_validator: REQUEST.SESSION['captcha_passed'] = True return self.getFormsTool().getContent( {'here': self, 'captcha_errors': captcha_validator}, 'naaya.content.meeting.subscription_signup') security.declareProtected(view, 'signup_successful') def signup_successful(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_signup_successful') security.declareProtected(view, 'subscribe') def subscribe(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_subscribe') def getSignups(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self._signups.itervalues() security.declareProtected(PERMISSION_ADMIN_MEETING, 'getSignup') def getSignup(self, key): """ """ return self._signups.get(key, None) def index_html(self, REQUEST): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_index') def _accept_signup(self, key): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(key, PARTICIPANT_ROLE) signup = self._signups[key] signup.accepted = 'accepted' email_sender = meeting.getEmailSender() email_sender.send_signup_accepted_email(signup) def _reject_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups[key] signup.accepted = 'rejected' participants = meeting.getParticipants() # delete the 'reimbursed' status participants.setAttendeeInfo([key], 'reimbursed', False) if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() email_sender.send_signup_rejected_email(signup) def _delete_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups.pop(key, None) if signup is None: return participants = meeting.getParticipants() if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() email_sender.send_signup_rejected_email(signup) def _is_signup(self, key): """ """ return key in self._signups def _is_accepted_signup(self, key): """ """ return self._is_signup(key) and \ self._signups[key].accepted == 'accepted' def _is_pending_signup(self, key): """ """ return self._is_signup(key) and \ self._signups[key].accepted == 'new' def manageSubscriptions(self, REQUEST): """ """ if not (self.checkPermissionAdminMeeting() or self.nfp_for_country()): raise Unauthorized uids = REQUEST.form.get('uids', []) assert isinstance(uids, list) for uid in uids: if 'accept' in REQUEST.form: if self._is_signup(uid): self._accept_signup(uid) else: self._accept_account_subscription(uid) elif 'reject' in REQUEST.form: if self._is_signup(uid): self._reject_signup(uid) else: self._reject_account_subscription(uid) elif 'delete' in REQUEST.form: if not self.checkPermissionAdminMeeting(): raise Unauthorized if self._is_signup(uid): self._delete_signup(uid) else: self._delete_account_subscription(uid) if 'set_representative' in REQUEST.form: self.setRepresentatives(REQUEST) elif 'unset_representative' in REQUEST.form: self.setRepresentatives(REQUEST, remove=True) elif 'set_reimbursement' in REQUEST.form: self.setReimbursement(REQUEST) elif 'unset_reimbursement' in REQUEST.form: self.setReimbursement(REQUEST, remove=True) elif 'save_changes' in REQUEST.form: self.save_changes(REQUEST) return REQUEST.RESPONSE.redirect(self.absolute_url()) security.declarePublic('welcome') def welcome(self, REQUEST, came_from=None): """ """ if 'logout' in REQUEST.form: REQUEST.SESSION['nymt-current-key'] = None return REQUEST.RESPONSE.redirect(self.getMeeting().absolute_url()) key = REQUEST.get('key', None) signup = self.getSignup(key) if self._is_signup(key): REQUEST.SESSION['nymt-current-key'] = key if came_from: return REQUEST.RESPONSE.redirect(came_from) else: return REQUEST.RESPONSE.redirect( self.getMeeting().absolute_url()) return self.getFormsTool().getContent( {'here': self, 'signup': signup}, 'naaya.content.meeting.subscription_welcome') def _add_account_subscription(self, uid, accept=False): """ """ # If the subscription already exists or the user is alread signed up # skip the whole thing if self._is_account_subscription(uid): return key = uid.replace('signup:', '') if self._is_signup(key): return site = self.getSite() meeting = self.getMeeting() name = getUserFullName(site, uid) # If for any reason we still don't have a name, at least use UID if not name: name = uid email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) if not organization: organization = self.get_survey_answer(uid, 'w_organization') if not organization: organization = self.get_survey_answer(uid, 'w_organisation') phone = getUserPhoneNumber(site, uid) if not phone: phone = self.get_survey_answer(uid, 'w_telephone') if not phone: phone = self.get_survey_answer(uid, 'w_phone') account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.insert(uid, account_subscription) if meeting.auto_register or accept: self._accept_account_subscription(uid) email_sender = self.getMeeting().getEmailSender() email_sender.send_account_subscription_email(account_subscription) security.declareProtected(PERMISSION_ADMIN_MEETING, 'update_account_subscription') def update_account_subscription(self, uid): """ """ site = self.getSite() name = getUserFullName(site, uid) email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) phone = getUserPhoneNumber(site, uid) account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.update({uid: account_subscription}) security.declareProtected(view, 'subscribe_accounts') def subscribe_accounts(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') # check Captcha/reCaptcha also for searching users if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha(recaptcha_response, REQUEST) if captcha_validator: return self.getFormsTool().getContent( {'here': self, 'captcha_errors': captcha_validator}, 'naaya.content.meeting.subscription_signup') else: REQUEST.SESSION['captcha_passed'] = True uids = REQUEST.form.get('uids', []) assert isinstance(uids, list) for uid in uids: self._add_account_subscription(uid) return REQUEST.RESPONSE.redirect( self.absolute_url() + '/subscribe_account_successful?uids='+','.join(uids)) security.declareProtected(view, 'subscribe_my_account') def subscribe_my_account(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') self._add_account_subscription(REQUEST.AUTHENTICATED_USER.getId()) if self.survey_required: site = self.getSite() path = str(self.survey_pointer) survey_ob = site.unrestrictedTraverse(path, None) if survey_ob is not None and \ survey_ob.meta_type == 'Naaya Mega Survey': answers = survey_ob.getAnswers() respondents = [a.respondent for a in answers] current_user = REQUEST.AUTHENTICATED_USER.getUserName() if current_user not in respondents: self.setSessionInfoTrans( 'Registration successfully sent for approval. ' 'Please also respond to the following questionaire.') return REQUEST.RESPONSE.redirect( '%s/%s' % (self.getSite().absolute_url(), self.survey_pointer)) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscribe_account_successful') security.declareProtected(view, 'subscribe_account_successful') def subscribe_account_successful(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_subscribe_successful') def getAccountSubscriptions(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self._account_subscriptions.itervalues() def getSubscriptions(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized subscriptions = (list(self._signups.itervalues()) + list(self._account_subscriptions.itervalues())) statuses = {'new': 0, 'accepted': 1, 'rejected': 2 } return sorted(subscriptions, key=lambda x: statuses.get(x.accepted)) security.declareProtected(PERMISSION_ADMIN_MEETING, 'getAccountSubscription') def getAccountSubscription(self, uid): """ """ return self._account_subscriptions.get(uid, None) def _is_account_subscription(self, uid): """ """ return uid in self._account_subscriptions and \ self._account_subscriptions[uid].accepted == 'accepted' def _accept_account_subscription(self, uid): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(uid, PARTICIPANT_ROLE) account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'accepted' email_sender = meeting.getEmailSender() email_sender.send_account_subscription_accepted_email( account_subscription) def _reject_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'rejected' participants = meeting.getParticipants() # remove the 'reimbursed' status participants.setAttendeeInfo([uid], 'reimbursed', False) if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() email_sender.send_account_subscription_rejected_email( account_subscription) def _delete_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions.pop(uid, None) if account_subscription is None: return participants = meeting.getParticipants() if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() email_sender.send_account_subscription_rejected_email( account_subscription) security.declareProtected(view, 'subscription_not_allowed') def subscription_not_allowed(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_not_allowed')
class Subscriptions(SimpleItem): security = ClassSecurityInfo() title = "Meeting registrations" def __init__(self, id): """ """ super(SimpleItem, self).__init__(id) self.id = id self._signups = OOBTree() self._account_subscriptions = OOBTree() security.declarePublic('getMeeting') def getMeeting(self): return self.aq_parent.aq_parent def _validate_signup(self, form): """ """ formdata = {} formerrors = {} keys = ('first_name', 'last_name', 'email', 'organization', 'phone') formdata = dict((key, form.get(key, '')) for key in keys) for key in formdata: if formdata[key] == '': formerrors[key] = 'This field is mandatory' if formerrors == {}: if formdata['email'].count('@') != 1: formerrors['email'] = ('An email address must contain ' 'a single @') if formerrors == {}: formerrors = None return formdata, formerrors def _add_signup(self, formdata): """ """ meeting = self.getMeeting() key = random_key() name = formdata['first_name'] + ' ' + formdata['last_name'] email = formdata['email'] organization = formdata['organization'] phone = formdata['phone'] signup = SignUp(key, name, email, organization, phone) self._signups.insert(key, signup) if meeting.auto_register: self._accept_signup(key) email_sender = self.getMeeting().getEmailSender() email_sender.send_signup_email(signup) if self.REQUEST.AUTHENTICATED_USER.getUserName() == 'Anonymous User': self.REQUEST.SESSION['nymt-current-key'] = key security.declareProtected(view, 'signup') def signup(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') if REQUEST.get('add_users'): return self.subscribe_accounts(REQUEST) if REQUEST.get('add_signup'): formdata, formerrors = self._validate_signup(REQUEST.form) # check Captcha/reCaptcha if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha( recaptcha_response, REQUEST) if captcha_validator: if formerrors is None: formerrors = {} formerrors['captcha'] = captcha_validator else: REQUEST.SESSION['captcha_passed'] = True if formerrors is not None: return self.getFormsTool().getContent( { 'here': self, 'formdata': formdata, 'formerrors': formerrors }, 'naaya.content.meeting.subscription_signup') else: self._add_signup(formdata) if self.getMeeting().survey_required: REQUEST.RESPONSE.redirect(self.getMeeting().absolute_url()) else: REQUEST.RESPONSE.redirect(self.absolute_url() + '/signup_successful') # check Captcha/reCaptcha also for searching users captcha_validator = None if (REQUEST.get('search_user') or REQUEST.get('search_user_with_role')): if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha( recaptcha_response, REQUEST) if not captcha_validator: REQUEST.SESSION['captcha_passed'] = True return self.getFormsTool().getContent( { 'here': self, 'captcha_errors': captcha_validator }, 'naaya.content.meeting.subscription_signup') security.declareProtected(view, 'signup_successful') def signup_successful(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_signup_successful') security.declareProtected(view, 'subscribe') def subscribe(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_subscribe') def getSignups(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self._signups.itervalues() security.declareProtected(PERMISSION_ADMIN_MEETING, 'getSignup') def getSignup(self, key): """ """ return self._signups.get(key, None) def index_html(self, REQUEST): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_index') def _accept_signup(self, key): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(key, PARTICIPANT_ROLE) signup = self._signups[key] signup.accepted = 'accepted' email_sender = meeting.getEmailSender() email_sender.send_signup_accepted_email(signup) def _reject_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups[key] signup.accepted = 'rejected' participants = meeting.getParticipants() # delete the 'reimbursed' status participants.setAttendeeInfo([key], 'reimbursed', False) if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() email_sender.send_signup_rejected_email(signup) def _delete_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups.pop(key, None) if signup is None: return participants = meeting.getParticipants() if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() email_sender.send_signup_rejected_email(signup) def _is_signup(self, key): """ """ return key in self._signups and \ self._signups[key].accepted == 'accepted' def _is_pending_signup(self, key): """ """ return key in self._signups and \ self._signups[key].accepted == 'new' def manageSubscriptions(self, REQUEST): """ """ if not (self.checkPermissionAdminMeeting() or self.nfp_for_country()): raise Unauthorized uids = REQUEST.form.get('uids', []) assert isinstance(uids, list) for uid in uids: if 'accept' in REQUEST.form: if self._is_signup(uid): self._accept_signup(uid) else: self._accept_account_subscription(uid) elif 'reject' in REQUEST.form: if self._is_signup(uid): self._reject_signup(uid) else: self._reject_account_subscription(uid) elif 'delete' in REQUEST.form: if not self.checkPermissionAdminMeeting(): raise Unauthorized if self._is_signup(uid): self._delete_signup(uid) else: self._delete_account_subscription(uid) if 'set_representative' in REQUEST.form: self.setRepresentatives(REQUEST) elif 'unset_representative' in REQUEST.form: self.setRepresentatives(REQUEST, remove=True) elif 'set_reimbursement' in REQUEST.form: self.setReimbursement(REQUEST) elif 'unset_reimbursement' in REQUEST.form: self.setReimbursement(REQUEST, remove=True) elif 'save_changes' in REQUEST.form: self.save_changes(REQUEST) return REQUEST.RESPONSE.redirect(self.absolute_url()) security.declarePublic('welcome') def welcome(self, REQUEST, came_from=None): """ """ if 'logout' in REQUEST.form: REQUEST.SESSION['nymt-current-key'] = None return REQUEST.RESPONSE.redirect(self.getMeeting().absolute_url()) key = REQUEST.get('key', None) signup = self.getSignup(key) if self._is_signup(key) or self._is_pending_signup(key): REQUEST.SESSION['nymt-current-key'] = key if came_from: return REQUEST.RESPONSE.redirect(came_from) else: return REQUEST.RESPONSE.redirect( self.getMeeting().absolute_url()) return self.getFormsTool().getContent({ 'here': self, 'signup': signup }, 'naaya.content.meeting.subscription_welcome') def _add_account_subscription(self, uid, accept=False): """ """ # If the subscription already exists or the user is alread signed up # skip the whole thing if self._is_account_subscription(uid): return key = uid.replace('signup:', '') if self._is_signup(key): return site = self.getSite() meeting = self.getMeeting() name = getUserFullName(site, uid) # If for any reason we still don't have a name, at least use UID if not name: name = uid email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) if not organization: organization = self.get_survey_answer(uid, 'w_organization') if not organization: organization = self.get_survey_answer(uid, 'w_organisation') phone = getUserPhoneNumber(site, uid) if not phone: phone = self.get_survey_answer(uid, 'w_telephone') if not phone: phone = self.get_survey_answer(uid, 'w_phone') account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.insert(uid, account_subscription) if meeting.auto_register or accept: self._accept_account_subscription(uid) email_sender = self.getMeeting().getEmailSender() email_sender.send_account_subscription_email(account_subscription) security.declareProtected(PERMISSION_ADMIN_MEETING, 'update_account_subscription') def update_account_subscription(self, uid): """ """ site = self.getSite() name = getUserFullName(site, uid) email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) phone = getUserPhoneNumber(site, uid) account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.update({uid: account_subscription}) security.declareProtected(view, 'subscribe_accounts') def subscribe_accounts(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') # check Captcha/reCaptcha also for searching users if not (self.checkPermissionSkipCaptcha() or REQUEST.SESSION.get('captcha_passed')): recaptcha_response = REQUEST.form.get('g-recaptcha-response', '') captcha_validator = self.validateCaptcha(recaptcha_response, REQUEST) if captcha_validator: return self.getFormsTool().getContent( { 'here': self, 'captcha_errors': captcha_validator }, 'naaya.content.meeting.subscription_signup') else: REQUEST.SESSION['captcha_passed'] = True uids = REQUEST.form.get('uids', []) assert isinstance(uids, list) for uid in uids: self._add_account_subscription(uid) return REQUEST.RESPONSE.redirect( self.absolute_url() + '/subscribe_account_successful?uids=' + ','.join(uids)) security.declareProtected(view, 'subscribe_my_account') def subscribe_my_account(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') self._add_account_subscription(REQUEST.AUTHENTICATED_USER.getId()) if self.survey_required: site = self.getSite() path = str(self.survey_pointer) survey_ob = site.unrestrictedTraverse(path, None) if survey_ob is not None and \ survey_ob.meta_type == 'Naaya Mega Survey': answers = survey_ob.getAnswers() respondents = [a.respondent for a in answers] current_user = REQUEST.AUTHENTICATED_USER.getUserName() if current_user not in respondents: self.setSessionInfoTrans( 'Registration successfully sent for approval. ' 'Please also respond to the following questionaire.') return REQUEST.RESPONSE.redirect( '%s/%s' % (self.getSite().absolute_url(), self.survey_pointer)) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscribe_account_successful') security.declareProtected(view, 'subscribe_account_successful') def subscribe_account_successful(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_subscribe_successful') def getAccountSubscriptions(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized return self._account_subscriptions.itervalues() def getSubscriptions(self): """ """ if not self.checkPermissionParticipateInMeeting(): raise Unauthorized subscriptions = (list(self._signups.itervalues()) + list(self._account_subscriptions.itervalues())) statuses = {'new': 0, 'accepted': 1, 'rejected': 2} return sorted(subscriptions, key=lambda x: statuses.get(x.accepted)) security.declareProtected(PERMISSION_ADMIN_MEETING, 'getAccountSubscription') def getAccountSubscription(self, uid): """ """ return self._account_subscriptions.get(uid, None) def _is_account_subscription(self, uid): """ """ return uid in self._account_subscriptions and \ self._account_subscriptions[uid].accepted == 'accepted' def _accept_account_subscription(self, uid): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(uid, PARTICIPANT_ROLE) account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'accepted' email_sender = meeting.getEmailSender() email_sender.send_account_subscription_accepted_email( account_subscription) def _reject_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'rejected' participants = meeting.getParticipants() # remove the 'reimbursed' status participants.setAttendeeInfo([uid], 'reimbursed', False) if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() email_sender.send_account_subscription_rejected_email( account_subscription) def _delete_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions.pop(uid, None) if account_subscription is None: return participants = meeting.getParticipants() if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() email_sender.send_account_subscription_rejected_email( account_subscription) security.declareProtected(view, 'subscription_not_allowed') def subscription_not_allowed(self, REQUEST): """ """ return self.getFormsTool().getContent( {'here': self}, 'naaya.content.meeting.subscription_not_allowed')
class Subscriptions(SimpleItem): security = ClassSecurityInfo() title = "Meeting registrations" def __init__(self, id): """ """ super(SimpleItem, self).__init__(id) self.id = id self._signups = OOBTree() self._account_subscriptions = OOBTree() security.declarePublic('getMeeting') def getMeeting(self): return self.aq_parent.aq_parent def _validate_signup(self, form): """ """ formdata = {} formerrors = {} keys = ('first_name', 'last_name', 'email', 'organization', 'phone') formdata = dict( (key, form.get(key, '')) for key in keys ) for key in formdata: if formdata[key] == '': formerrors[key] = 'This field is mandatory' if formerrors == {}: if formdata['email'].count('@') != 1: formerrors['email'] = 'An email address must contain a single @' if formerrors == {}: formerrors = None return formdata, formerrors def _add_signup(self, formdata): """ """ meeting = self.getMeeting() key = random_key() name = formdata['first_name'] + ' ' + formdata['last_name'] email = formdata['email'] organization = formdata['organization'] phone = formdata['phone'] signup = SignUp(key, name, email, organization, phone) self._signups.insert(key, signup) if meeting.auto_register: self._accept_signup(key) email_sender = self.getMeeting().getEmailSender() email_sender.send_signup_email(signup) security.declareProtected(view, 'signup') def signup(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') if REQUEST.REQUEST_METHOD == 'GET': return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_signup') if REQUEST.REQUEST_METHOD == 'POST': formdata, formerrors = self._validate_signup(REQUEST.form) #check Captcha/reCaptcha if not self.checkPermissionSkipCaptcha(): contact_word = REQUEST.form.get('contact_word', '') captcha_validator = self.validateCaptcha(contact_word, REQUEST) if captcha_validator: if formerrors is None: formerrors = {} formerrors['captcha'] = captcha_validator if formerrors is not None: return self.getFormsTool().getContent({'here': self, 'formdata': formdata, 'formerrors': formerrors}, 'naaya.content.meeting.subscription_signup') else: self._add_signup(formdata) REQUEST.RESPONSE.redirect(self.absolute_url() + '/signup_successful') security.declareProtected(view, 'signup_successful') def signup_successful(self, REQUEST): """ """ return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_signup_successful') security.declareProtected(view, 'subscribe') def subscribe(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_subscribe') security.declareProtected(PERMISSION_ADMIN_MEETING, 'getSignups') def getSignups(self): """ """ return self._signups.itervalues() security.declareProtected(PERMISSION_ADMIN_MEETING, 'getSignup') def getSignup(self, key): """ """ return self._signups.get(key, None) security.declareProtected(PERMISSION_ADMIN_MEETING, 'index_html') def index_html(self, REQUEST): """ """ return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_index') def _accept_signup(self, key): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(key, PARTICIPANT_ROLE) signup = self._signups[key] signup.accepted = 'accepted' email_sender = meeting.getEmailSender() result = email_sender.send_signup_accepted_email(signup) def _reject_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups[key] signup.accepted = 'rejected' participants = meeting.getParticipants() if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() result = email_sender.send_signup_rejected_email(signup) def _delete_signup(self, key): """ """ meeting = self.getMeeting() signup = self._signups.pop(key, None) if signup is None: return participants = meeting.getParticipants() if key in participants._get_attendees(): participants._del_attendee(key) email_sender = meeting.getEmailSender() result = email_sender.send_signup_rejected_email(signup) def _is_signup(self, key): """ """ return self._signups.has_key(key) and self._signups[key].accepted == 'accepted' security.declareProtected(PERMISSION_ADMIN_MEETING, 'manageSignups') def manageSignups(self, REQUEST): """ """ keys = REQUEST.form.get('keys', []) assert isinstance(keys, list) if 'accept' in REQUEST.form: for key in keys: self._accept_signup(key) elif 'reject' in REQUEST.form: for key in keys: self._reject_signup(key) elif 'delete' in REQUEST.form: for key in keys: self._delete_signup(key) return REQUEST.RESPONSE.redirect(self.absolute_url()) security.declarePublic('welcome') def welcome(self, REQUEST): """ """ if 'logout' in REQUEST.form: REQUEST.SESSION['nymt-current-key'] = None return REQUEST.RESPONSE.redirect(self.getMeeting().absolute_url()) key = REQUEST.get('key', None) signup = self.getSignup(key) if self._is_signup(key): REQUEST.SESSION['nymt-current-key'] = key return self.getFormsTool().getContent({'here': self, 'signup': signup}, 'naaya.content.meeting.subscription_welcome') def _add_account_subscription(self, uid): """ """ site = self.getSite() meeting = self.getMeeting() name = getUserFullName(site, uid) email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) if not organization: organization = self.get_survey_answer(uid, 'w_organization') if not organization: organization = self.get_survey_answer(uid, 'w_organisation') phone = getUserPhoneNumber(site, uid) if not phone: phone = self.get_survey_answer(uid, 'w_telephone') if not phone: phone = self.get_survey_answer(uid, 'w_phone') account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.insert(uid, account_subscription) if meeting.auto_register: self._accept_account_subscription(uid) email_sender = self.getMeeting().getEmailSender() email_sender.send_account_subscription_email(account_subscription) security.declareProtected(PERMISSION_ADMIN_MEETING, 'update_account_subscription') def update_account_subscription(self, uid): """ """ site = self.getSite() name = getUserFullName(site, uid) email = getUserEmail(site, uid) organization = getUserOrganization(site, uid) phone = getUserPhoneNumber(site, uid) account_subscription = AccountSubscription(uid, name, email, organization, phone) self._account_subscriptions.update({uid: account_subscription}) security.declareProtected(view, 'subscribe_account') def subscribe_account(self, REQUEST): """ """ meeting = self.getMeeting() if not meeting.allow_register: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscription_not_allowed') self._add_account_subscription(REQUEST.AUTHENTICATED_USER.getId()) if self.survey_required: site = self.getSite() path = str(self.survey_pointer) survey_ob = site.unrestrictedTraverse(path, None) if survey_ob is not None and survey_ob.meta_type == 'Naaya Mega Survey': answers = survey_ob.getAnswers() respondents = [a.respondent for a in answers] current_user = REQUEST.AUTHENTICATED_USER.getUserName() if current_user not in respondents: self.setSessionInfoTrans( 'Registration successfully sent for approval. ' 'Please also respond to the following questionaire.') return REQUEST.RESPONSE.redirect('%s/%s' % (self.getSite().absolute_url(), self.survey_pointer)) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/subscribe_account_successful') security.declareProtected(view, 'subscribe_account_successful') def subscribe_account_successful(self, REQUEST): """ """ return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_subscribe_successful') security.declareProtected(PERMISSION_ADMIN_MEETING, 'getAccountSubscriptions') def getAccountSubscriptions(self): """ """ return self._account_subscriptions.itervalues() security.declareProtected(PERMISSION_ADMIN_MEETING, 'getAccountSubscription') def getAccountSubscription(self, uid): """ """ return self._account_subscriptions.get(uid, None) def _is_account_subscription(self, uid): """ """ return self._account_subscriptions.has_key(uid) and self._account_subscriptions[uid].accepted == 'accepted' security.declareProtected(PERMISSION_ADMIN_MEETING, 'manageSignups') def manageAccountSubscriptions(self, REQUEST): """ """ uids = REQUEST.form.get('uids', []) assert isinstance(uids, list) if 'accept' in REQUEST.form: for uid in uids: self._accept_account_subscription(uid) elif 'reject' in REQUEST.form: for uid in uids: self._reject_account_subscription(uid) elif 'delete' in REQUEST.form: for uid in uids: self._delete_account_subscription(uid) return REQUEST.RESPONSE.redirect(self.absolute_url()) def _accept_account_subscription(self, uid): """ """ meeting = self.getMeeting() meeting.getParticipants()._set_attendee(uid, PARTICIPANT_ROLE) account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'accepted' email_sender = meeting.getEmailSender() result = email_sender.send_account_subscription_accepted_email(account_subscription) def _reject_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions[uid] account_subscription.accepted = 'rejected' participants = meeting.getParticipants() if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() result = email_sender.send_account_subscription_rejected_email(account_subscription) def _delete_account_subscription(self, uid): """ """ meeting = self.getMeeting() account_subscription = self._account_subscriptions.pop(uid, None) if account_subscription is None: return participants = meeting.getParticipants() if uid in participants._get_attendees(): participants._del_attendee(uid) email_sender = meeting.getEmailSender() result = email_sender.send_account_subscription_rejected_email(account_subscription) security.declareProtected(view, 'subscription_not_allowed') def subscription_not_allowed(self, REQUEST): """ """ return self.getFormsTool().getContent({'here': self}, 'naaya.content.meeting.subscription_not_allowed')
class fsIndex(object): def __init__(self, data=None): self._data = OOBTree() if data: self.update(data) def __getstate__(self): return dict(state_version=1, _data=[(k, v.toString()) for (k, v) in self._data.iteritems()]) def __setstate__(self, state): version = state.pop('state_version', 0) getattr(self, '_setstate_%s' % version)(state) def _setstate_0(self, state): self.__dict__.clear() self.__dict__.update(state) def _setstate_1(self, state): self._data = OOBTree([(k, fsBucket().fromString(v)) for (k, v) in state['_data']]) def __getitem__(self, key): return str2num(self._data[key[:6]][key[6:]]) def save(self, pos, fname): with open(fname, 'wb') as f: pickler = cPickle.Pickler(f, 1) pickler.fast = True pickler.dump(pos) for k, v in self._data.iteritems(): pickler.dump((k, v.toString())) pickler.dump(None) @classmethod def load(class_, fname): with open(fname, 'rb') as f: unpickler = cPickle.Unpickler(f) pos = unpickler.load() if not isinstance(pos, (int, long)): return pos # Old format index = class_() data = index._data while 1: v = unpickler.load() if not v: break k, v = v data[k] = fsBucket().fromString(v) return dict(pos=pos, index=index) def get(self, key, default=None): tree = self._data.get(key[:6], default) if tree is default: return default v = tree.get(key[6:], default) if v is default: return default return str2num(v) def __setitem__(self, key, value): value = num2str(value) treekey = key[:6] tree = self._data.get(treekey) if tree is None: tree = fsBucket() self._data[treekey] = tree tree[key[6:]] = value def __delitem__(self, key): treekey = key[:6] tree = self._data.get(treekey) if tree is None: raise KeyError, key del tree[key[6:]] if not tree: del self._data[treekey] def __len__(self): r = 0 for tree in self._data.itervalues(): r += len(tree) return r def update(self, mapping): for k, v in mapping.items(): self[k] = v def has_key(self, key): v = self.get(key, self) return v is not self def __contains__(self, key): tree = self._data.get(key[:6]) if tree is None: return False v = tree.get(key[6:], None) if v is None: return False return True def clear(self): self._data.clear() def __iter__(self): for prefix, tree in self._data.iteritems(): for suffix in tree: yield prefix + suffix iterkeys = __iter__ def keys(self): return list(self.iterkeys()) def iteritems(self): for prefix, tree in self._data.iteritems(): for suffix, value in tree.iteritems(): yield (prefix + suffix, str2num(value)) def items(self): return list(self.iteritems()) def itervalues(self): for tree in self._data.itervalues(): for value in tree.itervalues(): yield str2num(value) def values(self): return list(self.itervalues()) # Comment below applies for the following minKey and maxKey methods # # Obscure: what if `tree` is actually empty? We're relying here on # that this class doesn't implement __delitem__: once a key gets # into an fsIndex, the only way it can go away is by invoking # clear(). Therefore nothing in _data.values() is ever empty. # # Note that because `tree` is an fsBTree, its minKey()/maxKey() methods are # very efficient. def minKey(self, key=None): if key is None: smallest_prefix = self._data.minKey() else: smallest_prefix = self._data.minKey(key[:6]) tree = self._data[smallest_prefix] assert tree if key is None: smallest_suffix = tree.minKey() else: try: smallest_suffix = tree.minKey(key[6:]) except ValueError: # 'empty tree' (no suffix >= arg) next_prefix = prefix_plus_one(smallest_prefix) smallest_prefix = self._data.minKey(next_prefix) tree = self._data[smallest_prefix] assert tree smallest_suffix = tree.minKey() return smallest_prefix + smallest_suffix def maxKey(self, key=None): if key is None: biggest_prefix = self._data.maxKey() else: biggest_prefix = self._data.maxKey(key[:6]) tree = self._data[biggest_prefix] assert tree if key is None: biggest_suffix = tree.maxKey() else: try: biggest_suffix = tree.maxKey(key[6:]) except ValueError: # 'empty tree' (no suffix <= arg) next_prefix = prefix_minus_one(biggest_prefix) biggest_prefix = self._data.maxKey(next_prefix) tree = self._data[biggest_prefix] assert tree biggest_suffix = tree.maxKey() return biggest_prefix + biggest_suffix
class fsIndex(object): def __init__(self): self._data = OOBTree() def __getitem__(self, key): return str2num(self._data[key[:6]][key[6:]]) def get(self, key, default=None): tree = self._data.get(key[:6], default) if tree is default: return default v = tree.get(key[6:], default) if v is default: return default return str2num(v) def __setitem__(self, key, value): value = num2str(value) treekey = key[:6] tree = self._data.get(treekey) if tree is None: tree = fsBucket() self._data[treekey] = tree tree[key[6:]] = value def __delitem__(self, key): treekey = key[:6] tree = self._data.get(treekey) if tree is None: raise KeyError, key del tree[key[6:]] if not tree: del self._data[treekey] def __len__(self): r = 0 for tree in self._data.itervalues(): r += len(tree) return r def update(self, mapping): for k, v in mapping.items(): self[k] = v def has_key(self, key): v = self.get(key, self) return v is not self def __contains__(self, key): tree = self._data.get(key[:6]) if tree is None: return False v = tree.get(key[6:], None) if v is None: return False return True def clear(self): self._data.clear() def __iter__(self): for prefix, tree in self._data.iteritems(): for suffix in tree: yield prefix + suffix iterkeys = __iter__ def keys(self): return list(self.iterkeys()) def iteritems(self): for prefix, tree in self._data.iteritems(): for suffix, value in tree.iteritems(): yield (prefix + suffix, str2num(value)) def items(self): return list(self.iteritems()) def itervalues(self): for tree in self._data.itervalues(): for value in tree.itervalues(): yield str2num(value) def values(self): return list(self.itervalues()) # Comment below applies for the following minKey and maxKey methods # # Obscure: what if `tree` is actually empty? We're relying here on # that this class doesn't implement __delitem__: once a key gets # into an fsIndex, the only way it can go away is by invoking # clear(). Therefore nothing in _data.values() is ever empty. # # Note that because `tree` is an fsBTree, its minKey()/maxKey() methods are # very efficient. def minKey(self, key=None): if key is None: smallest_prefix = self._data.minKey() else: smallest_prefix = self._data.minKey(key[:6]) tree = self._data[smallest_prefix] assert tree if key is None: smallest_suffix = tree.minKey() else: try: smallest_suffix = tree.minKey(key[6:]) except ValueError: # 'empty tree' (no suffix >= arg) next_prefix = prefix_plus_one(smallest_prefix) smallest_prefix = self._data.minKey(next_prefix) tree = self._data[smallest_prefix] assert tree smallest_suffix = tree.minKey() return smallest_prefix + smallest_suffix def maxKey(self, key=None): if key is None: biggest_prefix = self._data.maxKey() else: biggest_prefix = self._data.maxKey(key[:6]) tree = self._data[biggest_prefix] assert tree if key is None: biggest_suffix = tree.maxKey() else: try: biggest_suffix = tree.maxKey(key[6:]) except ValueError: # 'empty tree' (no suffix <= arg) next_prefix = prefix_minus_one(biggest_prefix) biggest_prefix = self._data.maxKey(next_prefix) tree = self._data[biggest_prefix] assert tree biggest_suffix = tree.maxKey() return biggest_prefix + biggest_suffix
class fsIndex(object): def __init__(self): self._data = OOBTree() def __getitem__(self, key): return str2num(self._data[key[:6]][key[6:]]) def get(self, key, default=None): tree = self._data.get(key[:6], default) if tree is default: return default v = tree.get(key[6:], default) if v is default: return default return str2num(v) def __setitem__(self, key, value): value = num2str(value) treekey = key[:6] tree = self._data.get(treekey) if tree is None: tree = fsBucket() self._data[treekey] = tree tree[key[6:]] = value def __len__(self): r = 0 for tree in self._data.itervalues(): r += len(tree) return r def update(self, mapping): for k, v in mapping.items(): self[k] = v def has_key(self, key): v = self.get(key, self) return v is not self def __contains__(self, key): tree = self._data.get(key[:6]) if tree is None: return False v = tree.get(key[6:], None) if v is None: return False return True def clear(self): self._data.clear() def __iter__(self): for prefix, tree in self._data.iteritems(): for suffix in tree: yield prefix + suffix iterkeys = __iter__ def keys(self): return list(self.iterkeys()) def iteritems(self): for prefix, tree in self._data.iteritems(): for suffix, value in tree.iteritems(): yield (prefix + suffix, str2num(value)) def items(self): return list(self.iteritems()) def itervalues(self): for tree in self._data.itervalues(): for value in tree.itervalues(): yield str2num(value) def values(self): return list(self.itervalues()) # Comment below applies for the following minKey and maxKey methods # # Obscure: what if `tree` is actually empty? We're relying here on # that this class doesn't implement __delitem__: once a key gets # into an fsIndex, the only way it can go away is by invoking # clear(). Therefore nothing in _data.values() is ever empty. # # Note that because `tree` is an fsBTree, its minKey()/maxKey() methods are # very efficient. def minKey(self, key=None): if key is None: smallest_prefix = self._data.minKey() else: smallest_prefix = self._data.minKey(key[:6]) tree = self._data[smallest_prefix] assert tree if key is None: smallest_suffix = tree.minKey() else: try: smallest_suffix = tree.minKey(key[6:]) except ValueError: # 'empty tree' (no suffix >= arg) next_prefix = prefix_plus_one(smallest_prefix) smallest_prefix = self._data.minKey(next_prefix) tree = self._data[smallest_prefix] assert tree smallest_suffix = tree.minKey() return smallest_prefix + smallest_suffix def maxKey(self, key=None): if key is None: biggest_prefix = self._data.maxKey() else: biggest_prefix = self._data.maxKey(key[:6]) tree = self._data[biggest_prefix] assert tree if key is None: biggest_suffix = tree.maxKey() else: try: biggest_suffix = tree.maxKey(key[6:]) except ValueError: # 'empty tree' (no suffix <= arg) next_prefix = prefix_minus_one(biggest_prefix) biggest_prefix = self._data.maxKey(next_prefix) tree = self._data[biggest_prefix] assert tree biggest_suffix = tree.maxKey() return biggest_prefix + biggest_suffix