def search_phrase_index(index: OOBTree, query: str) -> List[Set[int]]: words = query.split() # If a query consists of two words if len(words) == 2: # Just search the index return index.get(fr'{normalize(words.pop(0))} {normalize(words.pop(0))}', None) else: # Otherwise, split the query into pairs of words phrase: List[str] = [] result: List[Set[int]] = [] for word in words: # Add word to the phrase (a pair of words) phrase.append(normalize(word)) # If we have two words in the phrase if len(phrase) == 2: # Search this phrase in the index item = index.get(fr'{phrase.pop(0)} {phrase[0]}', {}) # Append the search result (list of file's ids) to the result result.append(item) # If we have two lists in the result if len(result) == 2: # Intersect them result.append(set(result.pop(0)).intersection(set(result.pop(0)))) else: continue else: continue return result
class FieldTemplate(Folder): """ Field information """ implements(IFieldTemplate) def __init__(self, title=u"", description=u"", field_type=u""): self._storage = OOBTree() super(FieldTemplate, self).__init__() self.title = title self.description = description self.field_type = field_type def get_title(self): return self._storage.get('title', '') def set_title(self, value): self._storage['title'] = value title = property(get_title, set_title) def get_description(self): return self._storage.get('description', '') def set_description(self, value): self._storage['description'] = value description = property(get_description, set_description) def get_field_type(self): return self._storage.get('field_type', '') def set_field_type(self, value): self._storage['field_type'] = value field_type = property(get_field_type, set_field_type) def get_node(self, context, request, name = None, **kw): if name is None: name = self.__name__ fa = request.registry.getAdapter(self, IFieldAdapter, name = self.field_type) return fa.get_node(context, request, name, title = self.title, description = self.description, **kw)
def objects(self): """Returns the data to create the sitemap.""" catalog = getToolByName(self.context, 'portal_catalog') query = {} utils = getToolByName(self.context, 'plone_utils') query['portal_type'] = utils.getUserFriendlyTypes() ptool = getToolByName(self, 'portal_properties') siteProperties = getattr(ptool, 'site_properties') typesUseViewActionInListings = frozenset( siteProperties.getProperty('typesUseViewActionInListings', []) ) is_plone_site_root = IPloneSiteRoot.providedBy(self.context) if not is_plone_site_root: query['path'] = '/'.join(self.context.getPhysicalPath()) query['is_default_page'] = True default_page_modified = OOBTree() for item in catalog.searchResults(query, Language='all'): key = item.getURL().rsplit('/', 1)[0] value = (item.modified.micros(), item.modified.ISO8601()) default_page_modified[key] = value # The plone site root is not catalogued. if is_plone_site_root: loc = self.context.absolute_url() date = self.context.modified() # Comparison must be on GMT value modified = (date.micros(), date.ISO8601()) default_modified = default_page_modified.get(loc, None) if default_modified is not None: modified = max(modified, default_modified) lastmod = modified[1] yield { 'loc': loc, 'lastmod': lastmod, #'changefreq': 'always', # hourly/daily/weekly/monthly/yearly/never #'prioriy': 0.5, # 0.0 to 1.0 } query['is_default_page'] = False for item in catalog.searchResults(query, Language='all'): loc = item.getURL() date = item.modified # Comparison must be on GMT value modified = (date.micros(), date.ISO8601()) default_modified = default_page_modified.get(loc, None) if default_modified is not None: modified = max(modified, default_modified) lastmod = modified[1] if item.portal_type in typesUseViewActionInListings: loc += '/view' yield { 'loc': loc, 'lastmod': lastmod, #'changefreq': 'always', # hourly/daily/weekly/monthly/yearly/never #'prioriy': 0.5, # 0.0 to 1.0 }
class MobileImageShortURLStorage(ShortURLStorage): """ utility to keep track of shortened urls for mobile images """ implements(IMobileImageShortURLStorage) def __init__(self): self._map = OOBTree() self._reverse_map = OOBTree() def add(self, short, target): self._map[short] = target self._reverse_map[target] = short def remove(self, short): if self._map.has_key(short): target = self.get(short) del self._map[short] del self._reverse_map[target] def get(self, short, default=None): return self._map.get(short, default) def getkey(self, url, default=None): return self._reverse_map.get(url, default)
class OfflineEventsModule(Module): """ This module holds all the information needed to keep the creation process of the offline version of the events. That means all the news items and other related information. """ id = "offlineEvents" _offlineEventTypes = {"Queued": L_("Queued"), "Generated": L_("Generated"), "Failed": L_("Failed"), "Expired": L_("Expired")} def __init__(self): self._idxConf = OOBTree() self._offlineEventCounter = Counter() def getOfflineEventIndex(self): return self._idxConf def getOfflineEventByConfId(self, confId): return self._idxConf.get(confId, []) def getOfflineEventByFileId(self, confId, fileId): offline_request_list = self._idxConf.get(confId, []) for req in offline_request_list: if req.id == fileId: return req return None def addOfflineEvent(self, offlineEvent): confId = offlineEvent.conference.getId() if not self._idxConf.has_key(confId): lst = [] self._idxConf[confId] = lst else: lst = self._idxConf[confId] offlineEvent.id = self._offlineEventCounter.newCount() lst.append(offlineEvent) self._idxConf[confId] = lst def removeOfflineEvent(self, offlineEvent, del_file=False): if offlineEvent: confId = offlineEvent.conference.getId() lst = self._idxConf.get(confId,[]) if offlineEvent in lst: lst.remove(offlineEvent) self._idxConf[confId] = lst if del_file: self.removeOfflineFile(offlineEvent) else: raise Exception(_("OfflineEvent does not exist")) def removeOfflineFile(self, offlineEvent): filepath = offlineEvent.file.getFilePath() if os.path.isfile(filepath): os.remove(filepath) offlineEvent.status = "Expired" @classmethod def getOfflineEventTypes(self): return OfflineEventsModule._offlineEventTypes
class DeviceNetworksCache(object): """ Data structure used to store the networks devices belong to. OOBTree Key: Device.id Value: OOBtree Key: Network Value: number of ip addresses that belong to that network """ def __init__(self): self.cache = OOBTree() def add_device_network(self, device_id, network_id): """ device_id = Device.getId() network_id = IpNetwork.getPrimaryUrlPath() """ device_dict = self.cache.get(device_id) if device_dict is None: device_dict = OOBTree() self.cache[device_id] = device_dict network_value = device_dict.get(network_id, 0) + 1 device_dict[network_id] = network_value def remove_device_network(self, device_id, network_id): """ device_id = Device.getId() network_id = IpNetwork.getPrimaryUrlPath() """ device_dict = self.cache.get(device_id) if device_dict: network_value = device_dict.get(network_id, 0) - 1 if device_dict.has_key(network_id): if network_value > 0: device_dict[network_id] = network_value else: del device_dict[network_id] def remove_device(self, device_id): if self.cache.get(device_id): del self.cache[device_id] def get_device_networks(self, device_id): nets = set() if self.cache.get(device_id): nets = set(self.cache.get(device_id).keys()) return nets def __str__(self): to_str = "" for dev, nets in self.cache.iteritems(): to_str = to_str + "{0} => {1}\n".format(dev, len(nets.keys())) for net in nets.keys(): to_str = to_str + "\t{0}\n".format(net) return to_str
class DefaultTokenManager(Persistent): """Tokens manager persistent utility (per site) """ implements(ITokenManager) def __init__(self): # {token: user id, ...} self._token2uid = OOBTree() # {user id: token, ...} self._uid2token = OOBTree() return def userIdForToken(self, token): """See ITokensManager """ return self._token2uid.get(token, None) def tokenForUserId(self, user_id): """See ITokensManager """ if user_id in self._uid2token: return self._uid2token[user_id] # We'll make a token for this new user id return self.resetToken(user_id) def resetToken(self, user_id): """See ITokensManager """ old_token = self._uid2token.get(user_id, None) if old_token is not None: del self._token2uid[old_token] generator = getUtility(IUUIDGenerator) token = generator() self._token2uid[token] = user_id self._uid2token[user_id] = token return token def pruneUserId(self, user_id): """See ITokensManager """ token = self._uid2token[user_id] del self._uid2token[user_id] del self._token2uid[token] def knownUserIds(self): """See ITokensManager """ for user_id in self._uid2token.keys(): yield user_id
class UpgradeRegistry(object): """Registry of upgrade steps, by profile. Registry keys are profile ids. Each registry value is a nested mapping: - id -> step for single steps - id -> [ (id1, step1), (id2, step2) ] for nested steps """ def __init__(self): self._registry = OOBTree() def __getitem__(self, key): return self._registry.get(key) def keys(self): return self._registry.keys() def clear(self): self._registry.clear() def getUpgradeStepsForProfile(self, profile_id): """Return the upgrade steps mapping for a given profile, or None if there are no steps registered for a profile matching that id. """ profile_steps = self._registry.get(profile_id, None) if profile_steps is None: self._registry[profile_id] = OOBTree() profile_steps = self._registry.get(profile_id) return profile_steps def getUpgradeStep(self, profile_id, step_id): """Returns the specified upgrade step for the specified profile, or None if it doesn't exist. """ profile_steps = self._registry.get(profile_id, None) if profile_steps is not None: step = profile_steps.get(step_id, None) if step is None: for key in profile_steps.keys(): if type(profile_steps[key]) == list: subs = dict(profile_steps[key]) step = subs.get(step_id, None) if step is not None: break elif type(step) == list: subs = dict(step) step = subs.get(step_id, None) return step
class LocalAssignmentUtility(Persistent): """A utility for determining which rating categories are available for an object""" implements(IRatingCategoryAssignment) def __init__(self): self._mapping = OOBTree() def getId(self): return "contentratings" def _check_instance(self, content): return not IUnratable.providedBy(content) def supports_category(self, content, category): type_name = content.getPortalTypeName() # If the category is not assigned specifically to IDynamicType, # it should not be rejected if category not in self._avalable_categories: return True cat_name = category.name if self._check_instance(content) and cat_name in \ self._mapping.get(type_name, ()): return True return False def supported_categories(self, content): if not self._check_instance(content): return [] else: return self.categories_for_type(content.getPortalTypeName()) @property def _avalable_categories(self): return getUtility(IVocabularyFactory, 'plone.contentratings.categories')() def assign_categories(self, portal_type, categories): """Check that the given names are actually valid category names, if so assign them to the portal_type""" categories = set(categories) available_categories = set(t.value for t in self._avalable_categories) assert categories.issubset(available_categories) self._mapping[portal_type] = set(c.name for c in categories) def categories_for_type(self, portal_type): """Returns the categories set for a given portal type""" names = self._mapping.get(portal_type, ()) categories = self._avalable_categories return [categories.getTermByToken(n).value for n in names]
class BookingManagerConferenceIndex(Persistent): def __init__(self): self._tree = OOBTree() self._name = "bookingManagerByConf" def initialize(self, dbi=None): for i, conf in enumerate(ConferenceHolder()._getIdx().itervalues()): # Store CSBookingManager in the index csbm = getattr(conf, "_CSBookingManager", None) if csbm is None: csbm = CSBookingManager(conf) self.index(conf.getId(), csbm) if dbi and i % 1000 == 999: dbi.commit() if dbi: dbi.commit() def getName(self): return self._name def index(self, conf, csbm): if not self._tree.has_key(conf): self._tree[conf] = csbm self._tree._p_changed = 1 def unindex(self, conf): del self._tree[conf] self._tree._p_changed = 1 def get(self, conf): return self._tree.get(conf,None) def dump(self): return [(k, s) for k, s in self._tree.iteritems()]
class UIDMappingStorage(Persistent): """Stores a mapping between remote uids and local uids. """ implements(IUIDMappingStorage) def __init__(self): self._uidmap = OOBTree() def add(self, site_id, remote_uid, local_uid): if not site_id or not remote_uid or not local_uid: return self._uidmap[(site_id, remote_uid)] = local_uid def remove(self, site_id, remote_uid): del self._uidmap[(site_id, remote_uid)] def has_remote_uid(self, site_id, remote_uid): return bool(self._uidmap.has_key((site_id, remote_uid))) def get(self, site_id, remote_uid, default=None): return self._uidmap.get((site_id, remote_uid), default) def __iter__(self): return iter(self._uidmap)
class PrincipalAnnotationUtility(Persistent): """ Stores :class:`zope.annotation.interfaces.IAnnotations` for :class:`zope.security.interfaces.IPrinicipals`. """ __parent__ = None __name__ = None def __init__(self): self.annotations = OOBTree() def getAnnotations(self, principal): """ See :meth:`.IPrincipalAnnotationUtility.getAnnotations`. """ return self.getAnnotationsById(principal.id) def getAnnotationsById(self, principalId): """ See :meth:`.IPrincipalAnnotationUtility.getAnnotationsById`. """ annotations = self.annotations.get(principalId) if annotations is None: annotations = Annotations(principalId, store=self.annotations) annotations.__parent__ = self annotations.__name__ = principalId return annotations def hasAnnotations(self, principal): """ See :meth:`.IPrincipalAnnotationUtility.hasAnnotations`. """ return principal.id in self.annotations
class PrincipalAnnotationUtility(Persistent, Contained): """Stores `IAnnotations` for `IPrinicipals`. The utility ID is 'PrincipalAnnotation'. """ interface.implements(IPrincipalAnnotationUtility) def __init__(self): self.annotations = OOBTree() def getAnnotations(self, principal): """Return object implementing IAnnotations for the given principal. If there is no `IAnnotations` it will be created and then returned. """ return self.getAnnotationsById(principal.id) def getAnnotationsById(self, principalId): """Return object implementing `IAnnotations` for the given principal. If there is no `IAnnotations` it will be created and then returned. """ annotations = self.annotations.get(principalId) if annotations is None: annotations = Annotations(principalId, store=self.annotations) annotations.__parent__ = self annotations.__name__ = principalId return annotations def hasAnnotations(self, principal): """Return boolean indicating if given principal has `IAnnotations`.""" return principal.id in self.annotations
class Users(Folder, JSONRenderable): def __init__(self, **kw): super().__init__(**kw) self.providers = OOBTree() def add_provider(self, user, userpayload: dict): """ :param user: A Kedja User object :param userpayload: the result from the authomatic login, the user part as a dict """ provider = self.providers.setdefault(userpayload['provider'], OLBTree()) provider[userpayload['id']] = user.rid def find_providers_user(self, result, default=None): """ :param result: Authomatic login result :param default: Return value when not found :return: User or default """ user_rid = self.providers.get(result.provider.name, {}).get(result.user.id, None) return self.get_rid_user(user_rid, default) def get_rid_user(self, rid, default=None): """ :param rid: Users RID (resource ID) :param default: Return value when not found :return: User or default """ root = find_root(self) user = root.rid_map.get_resource(rid, default) if IUser.providedBy(user): return user return default
class ShortURLStorage(Persistent): """Stores short codes and urls to redirect to. """ implements(IShortURLStorage) def __init__(self): self._map = OOBTree() def add(self, short, target): self._map[short] = target def remove(self, short): if self._map.has_key(short): del self._map[short] def get(self, short, default=None): return self._map.get(short, default) def suggest(self): try: key = self._map.maxKey() except ValueError: # If the tree is empty return 'AAAAA' return _increment(key) def __getitem__(self, key): return self._map.items()[key] def __len__(self): return len(self._map)
class PasswordResetUtility(Persistent, Contained): implements(IPasswordResetUtility) def __init__(self): self.requests = OOBTree() def request(self, login, req): auth = getUtility(IAuthentication) pf = auth[u'principalfolder'] if login in pf: principal_id = pf.prefix + login code = random_string(30) data = OOBucket({'id': principal_id, 'time': time.time()}) self.requests[code] = data notify(PasswordResetRequest(principal_id, login, code, req)) else: raise KeyError def reset(self, login, code, password): auth = getUtility(IAuthentication) pf = auth[u'principalfolder'] if login in pf: principal_id = pf.prefix + login data = self.requests.get(code) if data and data['id'] == principal_id: ip = internal_principal(principal_id) ip.setPassword(password, "SSHA") notify(PasswordResetEvent(principal_id, password))
class PersitentOOBTree(Persistent): """A persitent wrapper around a OOBTree""" def __init__(self): self._data = OOBTree() Persistent.__init__(self) self.__len = Length() @Lazy def _PersitentOOBTree__len(self): l = Length() ol = len(self._data) if ol > 0: l.change(ol) self._p_changed = True return l def __len__(self): return self.__len() def __setitem__(self, key, value): # make sure our lazy property gets set l = self.__len self._data[key] = value l.change(1) def __delitem__(self, key): # make sure our lazy property gets set l = self.__len del self._data[key] l.change(-1) def __iter__(self): return iter(self._data) def __getitem__(self, key): """See interface `IReadContainer`. """ return self._data[key] def get(self, key, default=None): """See interface `IReadContainer`. """ return self._data.get(key, default) def __contains__(self, key): """See interface `IReadContainer`. """ return key in self._data has_key = __contains__ def items(self, key=None): return self._data.items(key) def keys(self, key=None): return self._data.keys(key) def values(self, key=None): return self._data.values(key)
class WorkflowRepository (SimpleItemWithProperties): """An object where a workflow tool stores object status. """ meta_type = 'Workflow Repository' security = ClassSecurityInfo() manage_options = ( {'label': 'Info', 'action': 'manage_main'}, ) + SimpleItemWithProperties.manage_options manage_main = PageTemplateFile('workflowRepositoryInfo', _www) _properties = () def __init__(self, id): self.id = id self._histories = OOBTree() security.declarePrivate('getHistory') def getHistory(self, id): return self._histories.get(id) security.declarePrivate('setHistory') def setHistory(self, id, h): self._histories[id] = h security.declareProtected(ManagePortal, 'countHistories') def countHistories(self): return len(self._histories)
class BookingManagerConferenceIndex(Persistent): def __init__(self): self._tree = OOBTree() self._name = "bookingManagerByConf" def initialize(self, dbi=None): pass def getName(self): return self._name def index(self, conf, csbm): if not self._tree.has_key(conf): self._tree[conf] = csbm self._tree._p_changed = 1 def unindex(self, conf): del self._tree[conf] self._tree._p_changed = 1 def get(self, conf): return self._tree.get(conf,None) def dump(self): return [(k, s) for k, s in self._tree.iteritems()]
class ShadowStorage(Persistent): """Container for Shadow Histories Only cares about containerish operations. """ def __init__(self): # Using an OOBtree to allow history ids of any type. The type # of the history ids highly depends on the unique id tool which # isn't under our control. self._storage = OOBTree() def isRegistered(self, history_id): """Returns True if a History With the Given History id Exists """ if history_id is None: return False return history_id in self._storage def getHistory(self, history_id, autoAdd=False): """Returns the History Object of the Given ``history_id``. Returns None if ``autoAdd`` is False and the history does not exist. Else prepares and returns an empty history. """ if history_id is None: return None # Create a new history if there isn't one yet if autoAdd and not self.isRegistered(history_id): self._storage[history_id] = ShadowHistory() return self._storage.get(history_id, None)
class Emojiable(Entity): def __init__(self, **kwargs): super(Emojiable, self).__init__(**kwargs) self.emojis = OOBTree() self.users_emoji = OOBTree() def add_emoji(self, emoji, user): user_oid = get_oid(user) current_emoji = self.get_user_emoji(user) if current_emoji: self.remove_emoji(current_emoji, user) if emoji: self.emojis.setdefault(emoji, PersistentList()) self.emojis[emoji].append(user_oid) self.users_emoji[user_oid] = emoji def remove_emoji(self, emoji, user): user_oid = get_oid(user) if emoji in self.emojis and \ user_oid in self.emojis[emoji]: self.emojis[emoji].remove(user_oid) self.users_emoji.pop(user_oid) def get_user_emoji(self, user): user_oid = get_oid(user) return self.users_emoji.get(user_oid, None) def can_add_reaction(self, user, process): return False
class RuleSet(Content): type_title = _("Ruleset") _referenced_questions = frozenset() choice_scores = None nav_visible = False @property def referenced_questions(self): return self._referenced_questions @referenced_questions.setter def referenced_questions(self, value): self._referenced_questions = frozenset(value) def __init__(self, **kw): super(RuleSet, self).__init__(**kw) self.choice_scores = OOBTree() def set_choice_score(self, question, choice, score): q_cluster = _question_by_type_or_id(question) c_cluster = _choice_by_type_or_id(choice) assert isinstance(score, int) choices = self.choice_scores.setdefault(q_cluster, OIBTree()) choices[c_cluster] = score def get_choice_score(self, question, choice, default = None): q_cluster = _question_by_type_or_id(question) c_cluster = _choice_by_type_or_id(choice) return self.choice_scores.get(q_cluster, {}).get(c_cluster, default)
class BookingManagerConferenceIndex(Persistent): def __init__(self): self._tree = OOBTree() self._name = "bookingManagerByConf" def initialize(self, dbi=None): for i, conf in enumerate(ConferenceHolder()._getIdx().itervalues()): # Store CSBookingManager in the index csbm = getattr(conf, "_CSBookingManager", None) if csbm is None: csbm = CSBookingManager(conf) self.index(conf.getId(), csbm) if dbi and i % 1000 == 999: dbi.commit() if dbi: dbi.commit() def getName(self): return self._name def index(self, conf, csbm): if not self._tree.has_key(conf): self._tree[conf] = csbm self._tree._p_changed = 1 def unindex(self, conf): del self._tree[conf] self._tree._p_changed = 1 def get(self, conf): return self._tree.get(conf, None) def dump(self): return [(k, s) for k, s in self._tree.iteritems()]
class SubscriptionStorage(object): def __init__(self): self.site = api.portal.get() try: self._data = self.site._subscribers except AttributeError: self._data = OOBTree() self.site._subscribers = self._data def add(self, email, data=None): email = email.lower() if data is None: data = {} data.update({ 'created': time(), 'code': make_random_key(100), 'confirmed': False, 'phone_number_confirmed': False, 'email': email }) self._data[email] = PersistentMapping(data) return data def remove(self, email): if email.lower() in self._data: del self._data[email.lower()] def get(self, email): return self._data.get(email.lower())
class PasswordResetUtility(Persistent, Contained): implements(IPasswordResetUtility) def __init__(self): self.requests = OOBTree() def request(self, login, req): auth = getUtility(IAuthentication) pf = auth[u'principalfolder'] if login in pf: principal_id = pf.prefix + login code = random_string(30) data = OOBucket({'id':principal_id, 'time':time.time()}) self.requests[code] = data notify(PasswordResetRequest(principal_id, login, code, req)) else: raise KeyError def reset(self, login, code, password): auth = getUtility(IAuthentication) pf = auth[u'principalfolder'] if login in pf: principal_id = pf.prefix + login data = self.requests.get(code) if data and data['id'] == principal_id: ip = internal_principal(principal_id) ip.setPassword(password, "SSHA") notify(PasswordResetEvent(principal_id, password))
class WorkflowRepository(SimpleItemWithProperties): """An object where a workflow tool stores object status. """ meta_type = 'Workflow Repository' security = ClassSecurityInfo() manage_options = ({ 'label': 'Info', 'action': 'manage_main' }, ) + SimpleItemWithProperties.manage_options manage_main = PageTemplateFile('workflowRepositoryInfo', _www) _properties = () def __init__(self, id=None): if id is not None: self._setId(id) self._histories = OOBTree() security.declarePrivate('getHistory') def getHistory(self, id): return self._histories.get(id) security.declarePrivate('setHistory') def setHistory(self, id, h): self._histories[id] = h security.declareProtected(ManagePortal, 'countHistories') def countHistories(self): return len(self._histories)
def get_words_by_joker(doc_index: OOBTree, gram_index: OOBTree, query: str) -> Set[str]: query: str = query.replace('*', '') words: Set[str] = set() # If a pattern consists of more than 3 letters # (this includes letters + symbols which represent # beginning and the end of a word) we make three grams # from it and search for them. if len(query) > 3: queries: List[str] = [query[i:i + 3] for i in range(len(query) - 2)] words = set(gram_index.get(queries.pop(0), [])) for item in queries: words = words.intersection(set(gram_index.get(item, []))) # If a pattern consists of just three letters # we search for it in the three gram index elif len(query) == 3: words: Set[str] = set(gram_index.get(query, [])) # If a pattern consists of two words # (letter + symbols which represent beginning # and the end of a word) we search for all grams # in the three gram index which begin or end with # this word. elif len(query) == 2: print(f'{Fore.YELLOW}' f'WARNING: One letter query with a joker' f' may process longer than queries ' f'which have more letters.' f'{Style.RESET_ALL}') for key in gram_index: if query in key: words.update(gram_index.get(key, [])) else: continue else: return set() if query.index('^') == 0: words = set( filter(lambda x: x.startswith(query.replace('^', '')), words)) else: words = set(filter(lambda x: x.endswith(query.replace('^', '')), words)) return words
class ContentTemplate(Folder): implements(IContentTemplate) title = None description = None fields = None def __init__(self): self._storage = OOBTree() super(ContentTemplate, self).__init__() def get_title(self): return self._storage.get('title', '') def set_title(self, value): self._storage['title'] = value title = property(get_title, set_title) def get_description(self): return self._storage.get('description', '') def set_description(self, value): self._storage['description'] = value description = property(get_description, set_description) def get_fields(self): return self._storage.get('fields', ()) def set_fields(self, value): if not isinstance(value, tuple): value = tuple(value) self._storage['fields'] = value fields = property(get_fields, set_fields) def get_schema(self, context, request, **kw): schema = colander.Schema() #gets the current schema for fieldname in self.order: schema.add(self[fieldname].get_node(context, request, **kw)) #adds field subnode to the current schema schema.bind(context = context, request = request, **kw) return schema def member_data_factory(self, values): #XXX This is an example #FIXME: Add factories later on from openmember.models.member_data import MemberData #FIXME: Soft validation goes here, i.e check if data contains errors or problems, but don't die on errors #Check that fields actually exist for k in values: if k not in self: raise KeyError("There's no field with name '%s' in %s" % (k, self)) return MemberData(values)
def btree(self, name): d = OOBTree() col = self.namemap[name] for i in range(len(self)): L = d.get(col[i], []) L.append(i) d[col[i]] = L self.indexes[name] = d
def group(self, seq): sortIndex = self._sortIndex sortReverse = self._sortReverse ns = len(seq) ni = len(sortIndex) if ns >= 0.1 * ni: # result large compared to index -- sort via index handled = IISet() hn = 0 _load = getattr(sortIndex, '_load', None) if _load is None: # not an optimized index items = sortIndex.items() _load = lambda (x1, x2): x2 if sortReverse: items.reverse() elif sortReverse: gRO = getattr(sortIndex, 'getReverseOrder', None) items = gRO and gRO() if items is None: items = list(sortIndex._index.keys()) items.reverse() else: items = sortIndex._index.keys() for i in items: ids = intersection(seq, _load(i)) if ids: handled.update(ids) hn += len(ids) yield i, ids if hn != len(seq): yield None, difference(seq, handled) else: # result relatively small -- sort via result m = OOBTree() keyFor = getattr(sortIndex, 'keyForDocument', None) # work around "nogopip" bug: it defines "keyForDocument" as an integer if not callable(keyFor): # this will fail, when the index neither defines a reasonable # "keyForDocument" nor "documentToKeyMap". In this case, # the index cannot be used for sorting. keyFor = lambda doc, map=sortIndex.documentToKeyMap(): map[doc] noValue = IITreeSet() for doc in seq.keys(): try: k = keyFor(doc) except KeyError: noValue.insert(doc) continue l = m.get(k) if l is None: l = m[k] = IITreeSet() l.insert(doc) items = m.items() if sortReverse: items = list(items) items.reverse() for i in items: yield i if noValue: yield None, noValue
class MembershipTerm(Folder): implements(IMembershipTerm) def __init__(self): self._storage = OOBTree() super(MembershipTerm, self).__init__() def get_start_date(self): return self._storage.get('start_date', '') def set_start_date(self, value): self._storage['start_date'] = value start_date = property(get_start_date, set_start_date) def get_end_date(self): return self._storage.get('end_date', '') def set_end_date(self, value): self._storage['end_date'] = value end_date = property(get_end_date, set_end_date)
class FriendlyNameStorage(Persistent): implements(IFriendlyNameStorage) def __init__(self): self._forward = OOBTree() # name -> uid self._reverse = OOBTree() # uid -> name def add(self, uid, name): """ Map name -> uid. """ store_name = name.lower() if store_name in self._forward: raise ValueError("%s already mapped" % name) if uid in self._reverse: raise ValueError("%s already has a friendly name" % uid) self._forward[store_name] = uid self._reverse[uid] = store_name def remove(self, uid): """ Remove mapping. This will be called when a folder is deleted, therefore we use the uid. """ marker = object() name = self._reverse.get(uid, marker) if name is not marker: del(self._reverse[uid]) try: del(self._forward[name]) except KeyError: # If it isn't there, good, that is the outcome we wanted, # right? pass def get(self, name, _marker=None): """ Look up name, map uid to an object and return it. """ return self._forward.get(name.lower(), _marker) def lookup(self, uid, _marker=None): """ Look up uid, return name. """ return self._reverse.get(uid, _marker) def __getitem__(self, key): return self._forward.items()[key] def __len__(self): return len(self._forward)
class IX_IndexHandle: def __init__(self, fileName, indexNo): self.filename = fileName + '.' + str(indexNo) self.indexNo = indexNo self.fileName = fileName with open(self.filename, "r", encoding="utf-8") as f: tree_dict = json.load(f) keys = list(map(int, tree_dict.keys())) values = list(tree_dict.values()) new_tree_dict = dict(zip(keys, values)) self.tree = Tree() self.tree.update(new_tree_dict) pass def __del__(self): pass def InsertEntry(self, record, rid): key = record[self.indexNo] l = self.tree.get(key) pageNum = rid.getPageNum() slotNum = rid.getSlotNum() if l: l.append((pageNum, slotNum)) else: self.tree[key] = [(pageNum, slotNum)] def DeleteEntry(self, record, rid): key = record[self.indexNo] l = self.tree.get(key) pageNum = rid.getPageNum() slotNum = rid.getSlotNum() if l: l.remove((pageNum, slotNum)) else: return False def ForcePages(self): with open(self.filename, "w", encoding="utf-8") as f: tree_dict = dict(self.tree.items()) json.dump(tree_dict, f)
class FriendlyNameStorage(Persistent): implements(IFriendlyNameStorage) def __init__(self): self._forward = OOBTree() # name -> uid self._reverse = OOBTree() # uid -> name def add(self, uid, name): """ Map name -> uid. """ store_name = name.lower() if store_name in self._forward: raise ValueError("%s already mapped" % name) if uid in self._reverse: raise ValueError("%s already has a friendly name" % uid) self._forward[store_name] = uid self._reverse[uid] = store_name def remove(self, uid): """ Remove mapping. This will be called when a folder is deleted, therefore we use the uid. """ marker = object() name = self._reverse.get(uid, marker) if name is not marker: del (self._reverse[uid]) try: del (self._forward[name]) except KeyError: # If it isn't there, good, that is the outcome we wanted, # right? pass def get(self, name, _marker=None): """ Look up name, map uid to an object and return it. """ return self._forward.get(name.lower(), _marker) def lookup(self, uid, _marker=None): """ Look up uid, return name. """ return self._reverse.get(uid, _marker) def __getitem__(self, key): return self._forward.items()[key] def __len__(self): return len(self._forward)
class BaseWiki(ContentContainer): interface.implements(IWiki, IWikiContents) maxOldLines = FieldProperty(IWiki['maxOldLines']) maxNewLines = FieldProperty(IWiki['maxNewLines']) parents = {} links = {} backlinks = {} def __init__(self, *args, **kw): super(BaseWiki, self).__init__(*args, **kw) self.links = OOBTree() self.backlinks = OOBTree() def relink(self, page, links): for link in self.links.get(page, ()): oldlinks = self.backlinks[link] oldlinks.remove(page) if not oldlinks: del self.backlinks[link] self.links[page] = OOTreeSet(links) for link in links: data = self.backlinks.get(link) if data is None: data = OOTreeSet() self.backlinks[link] = data data.insert(page) def __delitem__(self, key): # remove backlinks if key in self.links: for link in self.links[key]: oldlinks = self.backlinks[link] oldlinks.remove(key) if not oldlinks: del self.backlinks[link] del self.links[key] super(BaseWiki, self).__delitem__(key)
class SharedIndex(Persistent, Contained): implements(zope.catalog.interfaces.ICatalogIndex) def __init__(self): Persistent.__init__(self) Contained.__init__(self) self.uids = OOBTree() self.data = OOBTree() def get(self, docid, key): uid = self.uids.get(docid) if uid is None: return None return self.data.get((uid, key)) def __contains__(self, docid_key): docid, key = docid_key if docid not in self.uids: return False return (self.uids[docid], key) in self.data def index_doc(self, docid, link): self.uids[docid] = get_link_shared_uid(link) for key, value in link.shared.items(): self.data[self.uids[docid], key] = value def unindex_doc(self, docid): if docid not in self.uids: return unindex_uid = self.uids[docid] tounindex = set() for uid, key in self.data: if uid == unindex_uid: tounindex.add((uid, key)) for idx in tounindex: del self.data[idx] def clear(self): self.data.clear() self.uids.clear() def apply(query): raise NotImplemented('querying this index is not supported')
class UsedPasswordStorage(Persistent): """A local utility for storing a list of previously used passwords. """ implements(IUsedPasswordStorage) def __init__(self): self._user_passwords = OOBTree() def isPasswordUsed(self, login, password, history_size=0): """Query password store to see if password has been previously used. """ for hash in self.getPasswordsForUser(login, history_size): if AuthEncoding.pw_validate(hash, password): log.info("Password '%s' for user '%s' not valid (already used)" % (password, login)) return True log.info("Password '%s' for user '%s' valid" % (password, login)) return False def getPasswordsForUser(self, login, history_size=0): """Return a list of previously used paswords for a user. """ hashes = self._user_passwords.get(login, [])[-history_size:] return hashes def setPasswordForUser(self, login, password): """Add password to the list of previously used passwords for a user. """ hashes = self._user_passwords.get(login, []) hash = AuthEncoding.pw_encrypt(password) hashes.append(hash) self._user_passwords[login] = hashes log.info("Password '%s' for user '%s' stored" % (password, login)) def clearPasswordsForUser(self, login): """Remove stored passwords for a user. """ del self._user_passwords[login] def clearAllPasswords(self): """Remove stored passwords for all users. """ self._user_passwords.clear()
def add_device_network(self, device_id, network_id): """ device_id = Device.getId() network_id = IpNetwork.getPrimaryUrlPath() """ device_dict = self.cache.get(device_id) if device_dict is None: device_dict = OOBTree() self.cache[device_id] = device_dict network_value = device_dict.get(network_id, 0) + 1 device_dict[network_id] = network_value
class CacheStore(Persistent): """ basic persistent cache object see cache.txt """ def __init__(self, id_): self.id = id_ self.field={} self._cache = OOBTree() def __repr__(self): name = self.__class__.__name__ name = "%s '%s'" %(name, self.id) return "%s %s :: %s" %(name, self.field, [x for x in self._cache.items()]) def get(self, key, default=None): return self._cache.get(key, default) def set(self, key, value): self._cache[key] = value self._p_changed def getCache(self, key): subcache = self.field.get(key, _marker) if subcache is _marker: cache = Cache(parent=self, id_=self.id) self.field[key] = cache subcache = self.field[key] self._p_changed return subcache def remove(self, key): val = self._cache.get(key) if val: del self._cache[key] self._p_changed=True for name, fcache in self.field.items(): for slug, uid in fcache.items(): if uid==key: del fcache[slug]
def getPortletData(self, name): data = self.__data__.get('__portlets_data__') if data is None: data = OOBTree() self.__data__['__portlets_data__'] = data pdata = data.get(name) if pdata is None: pdata = OOBTree() data[name] = pdata return pdata
class BlobReferencesManager(Persistent, Contained): """Global blobs references manager utility The utility is used to keep all references of persistent files objects to their blobs; typically, when duplicating contents, we just increase blobs references instead of duplicating all their internal files contents, until they are modified. References management is done automatically when using file-related properties, like :py:class:`FileProperty <pyams_file.property.FileProperty>` or :py:class:`I18nFileProperty <pyams_file.property.I18nFileProperty>`. """ def __init__(self): self.refs = OOBTree() def add_reference(self, blob, reference): """Add reference to given blob""" oid = getattr(blob, '_p_oid') if not oid: getattr(reference, '_p_jar').add(blob) oid = getattr(blob, '_p_oid') oid = oid_repr(oid) refs = self.refs.get(oid) or set() refs.add(reference) self.refs[oid] = refs def drop_reference(self, blob, reference): """Remove reference from given blob""" oid = oid_repr(getattr(blob, '_p_oid')) refs = self.refs.get(oid) if refs is not None: if reference in refs: refs.remove(reference) if refs: self.refs[oid] = refs else: del self.refs[oid] del blob else: del blob
def __data__(self): site = getSite() data = getattr(site.aq_base, '__cp_data__', None) if data is None: data = OOBTree() site.__cp_data__ = data cdata = data.get(self.__id__) if cdata is None: cdata = OOBTree() data[self.__id__] = cdata return cdata
class ConsumerManager(Persistent, Contained): """\ A very basic consumer manager for the default layer. This manager only capture the very basics, and does not really allow users to add their own consumers and have them approved in a way that is more integrated into the Plone (or other) CMS. """ zope.component.adapts(IAttributeAnnotatable, zope.interface.Interface) zope.interface.implements(IConsumerManager) __dummy_key = fieldproperty.FieldProperty(IConsumer['key']) __dummy_secret = fieldproperty.FieldProperty(IConsumer['secret']) @property def DUMMY_KEY(self): return self.__dummy_key @property def DUMMY_SECRET(self): return self.__dummy_secret def __init__(self): self.__dummy_key = random_string(24) self.__dummy_secret = random_string(24) self._consumers = OOBTree() def add(self, consumer): assert IConsumer.providedBy(consumer) if self.get(consumer.key): raise ValueError('consumer %s already exists', consumer.key) self._consumers[consumer.key] = consumer def get(self, consumer_key, default=None): return self._consumers.get(consumer_key, default) def getValidated(self, consumer_key, default=None): # Provision for further checks by alternative implementations. return self.get(consumer_key, default) def getAllKeys(self): return self._consumers.keys() def makeDummy(self): return Consumer(str(self.DUMMY_KEY), str(self.DUMMY_SECRET)) def remove(self, consumer): if IConsumer.providedBy(consumer): consumer = consumer.key self._consumers.pop(consumer)
def get_all_words(tree: OOBTree, words: List[str] = None, word: str = '') -> List[str]: if words is None: words = [] for key in tree.keys(): if key == '^': words.append(word + key) continue else: get_all_words(tree.get(key), words, word + key) return words
class Session(Implicit, Persistent, RoleManager, Item): def __init__(self, sessionId): self._sessionId = sessionId self._questionId = OOBTree() self._answer = OOBTree() self._nav = OOBTree() self._context = OOBTree() self._loginStatus = OOBTree() self._page = OOBTree() self._query = OOBTree() self._qstPage = OOTreeSet() def addAnswer(self, questionId, answer, nav, time, context, loginStatus, page, query): if not self._questionId.has_key(time): self._questionId[time] = questionId self._answer[time] = answer self._nav[time] = nav self._context[time] = context self._loginStatus[time] = loginStatus self._page[time] = page self._query[time] = query self._qstPage.insert(str(questionId) + str(page)) return True return False def getTotFeedback(self): return len(self._questionId) #note: isAnswered(questionId, sessionId=sessionId, page=url) def isAnswered(self, questionId, **kwargs): if 'page' in kwargs: qstPage = str(questionId) + str(kwargs['page']) return True if self._qstPage.has_key(qstPage) else False else: return True if questionId in self._questionId.values() else False def getAnswerList(self): answers = [] for time in self._questionId.keys(): tmp = [ self._sessionId, time, self._questionId.get(time), self._answer.get(time), self._nav.get(time), self._context.get(time), self._loginStatus.get(time), self._page.get(time), self._query.get(time) ] answers.append(tmp) return answers
def create_index(self, index_data_type, metadata): # get the index of parameters in metadata require_index = GeneralFunction.get_index_of_metadata(self.metadata, [metadata]) # create index based on hash or btree if index_data_type == 'hash': new_dic = {} else: new_dic = OOBTree() for key in self.main_table: new_key = self.main_table[key].value[require_index[0]] if new_dic.get(new_key): new_dic[new_key].append(key) else: new_dic[new_key] = [key] self.index[metadata] = new_dic
class RegistrationStorage(object): attr_name = '_registration_confirmations' def __init__(self, context): self.context = context try: self._data = getattr(context, self.attr_name) except AttributeError: self._data = OOBTree() setattr(context, self.attr_name, self._data) def add(self, email, data=None): self.clean() email = email.lower() if data is None: data = {} data.update({ 'created': time(), 'code': make_random_key(100) }) self._data[email] = data return data def remove(self, email): if email.lower() in self._data: del self._data[email.lower()] def get(self, email): return self._data.get(email.lower()) def clean(self): now = time() delete = [] for email, item in self._data.items(): if not item: delete.append(email) continue created = item['created'] # delete all older than 1 hour if int((now - created) / 60 / 60) > 1: delete.append(email) for code in delete: del self._data[code]
def search_with_joker(doc_index: OOBTree, gram_index: OOBTree, query: str) -> Set[str]: jokers: List[str] = re.findall(r'\*', query) docs: Set[str] = set() words: Set[str] = set() if len(jokers) == 1: index: int = query.index('*') if index == 0: words = get_words_by_joker(doc_index, gram_index, f'{query}^') elif index == len(query) - 1: words = get_words_by_joker(doc_index, gram_index, f'^{query}') else: split_query = query.split('*') a: Set[str] = get_words_by_joker(doc_index, gram_index, f'^{split_query[0]}') b: Set[str] = get_words_by_joker(doc_index, gram_index, f'{split_query[1]}^') words = a.intersection(b) elif len(jokers) == 2: split_query = query.split('*') a: Set[str] = get_words_by_joker(doc_index, gram_index, f'^{split_query[0]}') b: Set[str] = get_words_by_joker(doc_index, gram_index, f'{split_query[2]}^') words = a.intersection(b) words = set( filter(lambda x: True if split_query[1] in x else False, words)) else: print(f'{Fore.RED}' f'ERROR: Queries with three jokers are not supported.' f'{Style.RESET_ALL}') for word in words: docs.update(doc_index.get(normalize(word), [])) return docs
class DomainAuthHelper(BasePlugin): """ Domain Authentication plugin for the PluggableAuthService """ security = ClassSecurityInfo() meta_type = 'Domain Authentication Plugin' security.declareProtected(manage_users, 'manage_map') manage_map = PageTemplateFile('www/daMatches', globals()) security.declareProtected(manage_users, 'manage_genericmap') manage_genericmap = PageTemplateFile('www/daGeneric', globals()) manage_options = ( BasePlugin.manage_options[:1] + ( { 'label': 'User Map', 'action': 'manage_map' # , 'help' : ( 'PluggableAuthService' # ,'matches.stx') }, { 'label': 'Generic Map', 'action': 'manage_genericmap' }) + BasePlugin.manage_options[1:]) def __init__(self, id, title=''): """ Initialize a new instance """ self.id = id self.title = title self._domain_map = OOBTree() security.declarePrivate('extractCredentials') def extractCredentials(self, request): """ Extract credentials from 'request'. """ creds = {} remote_host = request.get('REMOTE_HOST', '') if remote_host: creds['remote_host'] = request.get('REMOTE_HOST', '') try: remote_address = request.getClientAddr() except AttributeError: remote_address = request.get('REMOTE_ADDR', '') if remote_host or remote_address: creds['remote_host'] = remote_host creds['remote_address'] = remote_address return creds security.declarePrivate('authenticateCredentials') def authenticateCredentials(self, credentials): """ Fulfill AuthenticationPlugin requirements """ login = credentials.get('login', '') r_host = credentials.get('remote_host', '') r_address = credentials.get('remote_address', '') matches = self._findMatches(login, r_host, r_address) if len(matches) > 0: if login: return (login, login) else: best_match = matches[0] u_name = best_match.get('username', 'remote') return (best_match.get('user_id', u_name), u_name) return (None, None) security.declarePrivate('getRolesForPrincipal') def getRolesForPrincipal(self, user, request=None): """ Fulfill RolesPlugin requirements """ roles = [] if request is None: # Without request there is no way I can do anything... return tuple(roles) uname = user.getUserName() if uname.find('Remote User') != -1: uname = '' matches = self._findMatches(uname, request.get('REMOTE_HOST', ''), request.getClientAddr()) # We want to grab the first match because it is the most specific if len(matches) > 0: roles = matches[0].get('roles', []) return tuple(roles) security.declarePrivate('_findMatches') def _findMatches(self, login, r_host='', r_address=''): """ Find the match """ matches = [] if not r_host and not r_address: return tuple(matches) all_info = list(self._domain_map.get(login, [])) all_info.extend(self._domain_map.get('', [])) if not r_host: try: r_host = socket.gethostbyaddr(r_address)[0] except socket.error: pass if not r_address: try: r_address = socket.gethostbyname(r_host) except socket.error: pass if not r_host and not r_address: return tuple(matches) candidates = [r_host, r_address] for match_info in all_info: m = [] m_type = match_info['match_type'] m_string = match_info['match_string'] filter = match_info.get('match_filter') if filter is None: # legacy data filter = _MATCH_TYPE_FILTERS[m_type](m_string) matches.extend([match_info for x in candidates if filter(x)]) return tuple(matches) security.declareProtected(manage_users, 'listMatchTypes') def listMatchTypes(self): """ Return a sequence of possible match types """ return _MATCH_TYPE_FILTERS.keys() security.declareProtected(manage_users, 'listMappingsForUser') def listMappingsForUser(self, user_id=''): """ List the mappings for a specific user """ result = [] record = self._domain_map.get(user_id, []) for match_info in record: result.append({ 'match_type': match_info['match_type'], 'match_string': match_info['match_string'], 'match_id': match_info['match_id'], 'roles': match_info['roles'], 'username': match_info['username'] }) return result security.declareProtected(manage_users, 'manage_addMapping') def manage_addMapping(self, user_id='', match_type='', match_string='', username='', roles=[], REQUEST=None): """ Add a mapping for a user """ msg = '' try: filter = _MATCH_TYPE_FILTERS[match_type](match_string) except KeyError: msg = 'Unknown match type %s' % match_type except re.error: msg = 'Invalid regular expression %s' % match_string except ValueError, e: msg = 'Invalid match string %s (%s)' % (match_string, e) if not match_string: msg = 'No match string specified' if msg: if REQUEST is not None: return self.manage_map(manage_tabs_message=msg) raise ValueError, msg record = self._domain_map.get(user_id, []) match = { 'match_type': match_type, 'match_string': match_string, 'match_filter': filter, 'match_id': '%s_%s' % (user_id, str(time.time())), 'username': user_id or username or 'Remote User', 'roles': roles } if match not in record: record.append(match) else: msg = 'Match already exists' self._domain_map[user_id] = record if REQUEST is not None: msg = msg or 'Match added.' if user_id: return self.manage_map(manage_tabs_message=msg) else: return self.manage_genericmap(manage_tabs_message=msg)
class Issue(ListText): "this object represents a single votable Issue" security = ClassSecurityInfo() meta_type = "Issue" storage = None votes = None description = '' addType = 'IssueChoice' selectionType = "radio" selectionLimit = 1 selectionLimitMin = 0 format = '<div>%s</div>' MustSelectOne = '<strong>At least one choice must be made.</strong>' TooManyItems = '<strong>Too many items where selected.</strong>' NotEnoughItems = '<strong>Not Enough items where selected.</strong>' BadItemSelected = '''<strong>An item was selected that does not exist. You should never see this message please email the webmaster.</strong>''' voteText = '''%(error)s<div class="issue"><div class="issueDescription">%(description)s</div> <div class="issueChoices">%(issues)s</div></div> ''' alreadyVotedText = '<p>You have already voted</p>' noVotingAllowed = '<p>Voting is not currently allowed</p>' thankYouText = '<p>Thank you for voting</p>' deleteButtonText = 'Delete Issue Choice' addButtonText = 'Add Issue Choice' selectionAllowedTypes = (('radio', 'Single Selection'), ('checkbox', 'Multiple Selection')) classConfig = {} classConfig['selectionLimit'] = { 'name': 'If you have selected multiple selection mode how many choices can people make (MAX)?', 'type': 'int' } classConfig['selectionLimitMin'] = { 'name': 'If you have selected multiple selection mode how many choices do people have to make? (MIN)', 'type': 'int' } classConfig['selectionType'] = { 'name': 'Allowed Selections', 'type': 'list', 'values': selectionAllowedTypes } classConfig['description'] = {'name': 'Issue Description', 'type': 'text'} drawDict = ListText.drawDict.copy() drawDict['vote'] = 'drawVote' drawDict['voteChecked'] = 'drawVoteChecked' drawDict['report'] = 'drawReport' security.declareProtected('View management screens', 'edit') def edit(self, *args, **kw): "Inline edit view" temp = self.editSingleConfig('description') temp += self.editSingleConfig('selectionType') temp += self.editSingleConfig('selectionLimit') temp += self.editSingleConfig('selectionLimitMin') return temp + ListText.edit(self) security.declareProtected('CompoundDoc: Voting', 'alternate_security_edit') def alternate_security_edit(self, dict): "save the voting information if it is okay to do so" choices = None if 'choices' in dict: choices = dict.get('choices').values() del dict['choices'] if choices: choices = [choice for choice in choices if choice] uid = self.getUID() if self.isOkayToVote(uid): self.vote(uid, choices) security.declareProtected('CompoundDoc: Voting', 'drawVote') def drawVote(self): "draw the voting interface" return self.drawVoteChecked()[1] security.declareProtected('CompoundDoc: Voting', 'drawVoteChecked') def drawVoteChecked(self): "draw the voting interface" structure = self.voteStructure() structure['error'], messageType = self.drawError() uid = self.getUID() if messageType == 'thankYouText': return (False, self.getMessage('thankYouText', structure)) if self.voteEnabled: if self.isOkayToVote(uid): return (True, self.getMessage('voteText', structure)) elif self.alreadyVoted(uid): return (False, self.getMessage('alreadyVotedText', structure)) else: return (False, self.getMessage('notAllowedToVote', structure)) else: return (False, self.getMessage('noVotingAllowed', structure)) security.declarePrivate('getMessage') def getMessage(self, messageType, lookup): """if we have a url for a set of messages to use on errors go ahead and use that otherwise use the default string we have and get variables from this lookup(dictionary) object""" folder = self.getMessageFolder() if folder is not None: item = getattr(folder, messageType, None) if item is not None: return item.__of__(self)(lookup) return getattr(self, messageType) % lookup security.declarePrivate('drawError') def drawError(self): "draw any needed any message" return self.getErrorMessage() def hasErrorMessage(self): "do we have an error message to draw?" messages = self.REQUEST.other.get('messages', {}) return self.getPhysicalPath() in messages def getErrorMessage(self): "get the current Error Message" messages = self.REQUEST.other.get('messages', {}) return messages.get(self.getPhysicalPath(), ('', '')) def writeErrorMessage(self, message, messageType): "write the current error message so we can get it later" messages = self.REQUEST.other.get('messages', {}) messages[self.getPhysicalPath()] = (message, messageType) self.REQUEST.other['messages'] = messages security.declarePrivate('voteStructure') def voteStructure(self): "get the voting data structure" lookup = {} lookup['description'] = self.description temp = [] if len(self): if self.selectionType == 'radio': choices = [(choice.view(), choice.view()) for choice in self] temp = self.radio_list('radio', choices, containers=('choices', )) formName = self.formName('radio', 'string', ('choices', )) temp.append( '<input type="hidden" name="%s:default" value="">' % formName) elif self.selectionType == 'checkbox': formName = self.formName('default', 'string', ('choices', )) temp.append( '<input type="hidden" name="%s:default" value="">' % formName) for choice in self: temp.append( self.check_box(choice.getId(), choice.view(), ('choices', )) + choice.view()) if temp: temp = [self.format % i for i in temp] lookup['issues'] = ''.join(temp) return lookup security.declarePrivate('isOkayToVote') def isOkayToVote(self, uid): "is it okay to vote" try: if getSecurityManager().validate( None, self, 'drawVote', self.drawVote ) and self.voteEnabled and not self.alreadyVoted( uid) and self.isOkayToVoteUserDefined(): return True except Unauthorized: pass security.declarePrivate('alreadyVoted') def alreadyVoted(self, uid): "is it okay to vote" return self.getStorage().has_key(uid) security.declarePrivate('drawReport') def drawReport(self): "draw a basic report of the voting results" results = self.report() results = [(votes, issueName) for issueName, votes in results] results.sort(reverse=True) results.insert(0, ('Number of Votes', 'Choice')) results.append(('Total Number of Votes', len(self.getStorage()))) temp = '<p>%s</p>' % self.description temp += self.createTable(results) return temp security.declarePrivate('report') def report(self): "return the report of how the votes went" return self.getVotes().items() security.declareProtected('CompoundDoc: Voting Stats', 'getVotes') def getVotes(self): "get the current vote information" if self.votes is not None: return self.votes return OOBTree() security.declareProtected('CompoundDoc: Voting Stats', 'getStorage') def getStorage(self): "get the current storage information which is a mapping of who has voted" if self.storage is not None: return self.storage return OOBTree() security.declareProtected('View', 'vote') def vote(self, uid, choices): "increase the count for this choice in votes if this uid is not already recorded" if self.isValidChoices(choices) and not self.getStorage().has_key(uid): self.uidVoted(uid) self.choiceSelected(choices) security.declarePrivate('isValidChoices') def isValidChoices(self, choices): "return true if all of the choices given are valid given the state of this object" allowedLength = 1 allowedLengthMin = 0 lookup = {} if self.selectionType == "checkbox": allowedLength = self.selectionLimit allowedLengthMin = self.selectionLimitMin lookup['selected'] = len(choices) lookup['max_selected'] = allowedLength lookup['min_selected'] = allowedLengthMin lookup['bad_choice'] = '' if not len(choices): self.writeErrorMessage(self.getMessage('MustSelectOne', lookup), 'MustSelectOne') return 0 if len(choices) > allowedLength: self.writeErrorMessage(self.getMessage('TooManyItems', lookup), 'TooManyItems') return 0 if len(choices) < allowedLengthMin: self.writeErrorMessage(self.getMessage('NotEnoughItems', lookup), 'NotEnoughItems') return 0 allowedChoices = [i.view() for i in self] for choice in choices: if choice not in allowedChoices: lookup['bad_choice'] = choice self.writeErrorMessage( self.getMessage('BadItemSelected', lookup), 'BadItemSelected') return 0 return 1 security.declarePrivate('uidVoted') def uidVoted(self, uid): "record that this uid has voted for this issue" if self.storage is None: self.storage = OOBTree() if not self.storage.has_key(uid): self.storage[uid] = True security.declarePrivate('choiceSelected') def choiceSelected(self, choices): "increment the counter for this choice" if self.votes is None: self.votes = OOBTree() lookup = {} lookup['choices'] = choices self.writeErrorMessage(self.getMessage('thankYouText', lookup), 'thankYouText') for choice in choices: count = self.votes.get(choice, 0) count += 1 self.votes[choice] = count security.declarePrivate('classUpgrader') def classUpgrader(self): "upgrade this class" return None