def __init__(self): self._quips = OOBTree() self._followed = OOBTree() self._followed_tags = OOBTree() # AppendStack defaults seem too low for search to make sense self._recent = AppendStack(max_layers=20, max_length=500) self._archive = Archive()
class SiteEvents(Persistent): implements(ISiteEvents) def __init__(self): self._stack = AppendStack(APPENDSTACK_MAX_LAYERS, APPENDSTACK_MAX_LENGTH) def __iter__(self): """ See ISiteEvents. """ for gen, index, mapping in self._stack: yield gen, index, mapping # TODO: iterate archive? def checked(self, principals, created_by): """ See ISiteEvents. """ if principals: principals = set(principals) for gen, index, mapping in self._stack: userid = mapping.get('userid', None) created = mapping.get('content_creator', userid) if created_by and created != created_by and userid != created_by: continue allowed = set(mapping.get('allowed', ())) if not principals or allowed & principals: yield gen, index, mapping # TODO: iterate archive? def newer(self, latest_gen, latest_index, principals=None, created_by=None): """ See ISiteEvents. """ iterable = self.checked(principals, created_by) for gen, index, mapping in iterable: if (gen, index) > (latest_gen, latest_index): yield gen, index, mapping # TODO: iterate archive? def older(self, earliest_gen, earliest_index, principals=None, created_by=None): """ See ISiteEvents. """ iterable = self.checked(principals, created_by) for gen, index, mapping in iterable: if (gen, index) < (earliest_gen, earliest_index): yield gen, index, mapping # TODO: iterate archive? def push(self, **kw): """ See ISiteEvents. """ # TODO: pruner=??? self._stack.push(PersistentMapping(kw))
class Chirps(Persistent): def __init__(self): self._stack = AppendStack() def __iter__(self): for gen, index, mapping in self._stack: yield gen, index, mapping def checked(self, follows): for gen, index, mapping in self._stack: created_by = mapping.get('created_by', None) if created_by in follows: yield gen, index, mapping def newer(self, latest_gen, latest_index, follows): iterable = self.checked(follows) for gen, index, mapping in iterable: if (gen, index) > (latest_gen, latest_index): yield gen, index, mapping def older(self, earliest_gen, earliest_index, follows): iterable = self.checked(follows) for gen, index, mapping in iterable: if (gen, index) < (earliest_gen, earliest_index): yield gen, index, mapping def push(self, **kw): self._stack.push(PersistentMapping(kw),)
class Like(Persistent): ''' Like content. ''' implements(ILike) def __init__(self, user=None): self.users = AppendStack() self._count = 0 if user: self.users.push(user) self._count += 1 def __len__(self): return len(list(self.users)) def count(self): return self._count def add(self, user): self.users.push(user) self._count += 1 def has_user(self, user): for x,y,u in self.users: log.debug('%s=%s' % (user, u)) if user == u: return True return False
class Chirps(Persistent): def __init__(self): self._stack = AppendStack() def __iter__(self): for gen, index, mapping in self._stack: yield gen, index, mapping def checked(self, follows): for gen, index, mapping in self._stack: created_by = mapping.get('created_by', None) if created_by in follows: yield gen, index, mapping def newer(self, latest_gen, latest_index, follows): iterable = self.checked(follows) for gen, index, mapping in iterable: if (gen, index) > (latest_gen, latest_index): yield gen, index, mapping def older(self, earliest_gen, earliest_index, follows): iterable = self.checked(follows) for gen, index, mapping in iterable: if (gen, index) < (earliest_gen, earliest_index): yield gen, index, mapping def push(self, **kw): self._stack.push(PersistentMapping(kw), )
class SiteEvents(Persistent): implements(ISiteEvents) def __init__(self): self._stack = AppendStack() def __iter__(self): """ See ISiteEvents. """ for gen, index, mapping in self._stack: yield gen, index, mapping # TODO: iterate archive? def checked(self, principals, created_by): """ See ISiteEvents. """ if principals: principals = set(principals) for gen, index, mapping in self._stack: userid = mapping.get('userid', None) created = mapping.get('content_creator', userid) if created_by and created != created_by and userid != created_by: continue allowed = set(mapping.get('allowed', ())) if not principals or allowed & principals: yield gen, index, mapping # TODO: iterate archive? def newer(self, latest_gen, latest_index, principals=None, created_by=None): """ See ISiteEvents. """ iterable = self.checked(principals, created_by) for gen, index, mapping in iterable: if (gen, index) > (latest_gen, latest_index): yield gen, index, mapping # TODO: iterate archive? def older(self, earliest_gen, earliest_index, principals=None, created_by=None): """ See ISiteEvents. """ iterable = self.checked(principals, created_by) for gen, index, mapping in iterable: if (gen, index) < (earliest_gen, earliest_index): yield gen, index, mapping # TODO: iterate archive? def push(self, **kw): """ See ISiteEvents. """ self._stack.push(PersistentMapping(kw), # TODO: pruner=??? ) def supported_ctx_ifaces(self): return (ICommunity, IProfile)
def test_addQuip_with_pruning(self): from appendonly import AppendStack cb = self._makeOne() # replace the stack with one which overflows quickly. cb._recent = AppendStack(1, 1) name1 = cb.addQuip('TEXT1', 'USER1') name2 = cb.addQuip('TEXT2', 'USER2') name3 = cb.addQuip('TEXT3', 'USER3') self.assertEqual(len(cb), 3) self.assertEqual(sorted(cb), sorted([name3, name2, name1])) # Overflowed twice self.assertEqual(cb._archive._generation, 1)
class Chatterbox(Persistent): implements(IChatterbox) def __init__(self): self._quips = OOBTree() self._followed = OOBTree() self._followed_tags = OOBTree() # AppendStack defaults seem too low for search to make sense self._recent = AppendStack(max_layers=20, max_length=500) self._archive = Archive() def __iter__(self): return iter(self._quips) def __len__(self): """ See IChatterbox. """ return len(self._quips) def __getitem__(self, key): """ See IChatterbox. """ return self._quips[key] def addQuip(self, text, creator, repost=None, reply=None): """ See IChatterbox. """ quip = Quip(text, creator, repost, reply) sha = hashlib.sha512(text) sha.update(creator) sha.update(quip.created.isoformat()) key = sha.hexdigest() self._quips[key] = quip quip.__name__ = key quip.__parent__ = self self._recent.push(quip, self._archive.addLayer) return key def listFollowed(self, userid): """ See IChatterbox. """ return self._followed.get(userid, ()) def setFollowed(self, userid, followed): """ See IChatterbox. """ self._followed[userid] = tuple(followed) def listFollowedTags(self, userid): """ See IChatterbox. """ return self._followed_tags.get(userid, ()) def setFollowedTags(self, userid, followed_tags): """ See IChatterbox. """ self._followed_tags[userid] = tuple(followed_tags) def listFollowing(self, userid): """ See IChatterbox. """ for name, following in self._followed.items(): if userid in following: yield name def recent(self): """ See IChatterbox. """ for gen, index, quip in self._recent: yield quip def recentFollowed(self, userid): """ See IChatterbox. """ creators = (userid, ) + self.listFollowed(userid) tags = set(self.listFollowedTags(userid)) names = set(creators) for quip in self.recent(): if quip.creator in creators or tags & quip.tags: yield quip def recentFollowedTags(self, userid): """ See IChatterbox. """ tags = set(self.listFollowedTags(userid)) for quip in self.recent(): if tags & quip.tags: yield quip def recentWithTag(self, tag): """ See IChatterbox. """ for quip in self.recent(): if tag in quip.tags: yield quip def recentWithCommunities(self, *communities): """ See IChatterbox. """ communities = set(communities) for quip in self.recent(): if communities & quip.communities: yield quip def recentWithCreators(self, *creators): """ See IChatterbox. """ names = set(creators) for quip in self.recent(): if quip.creator in creators: yield quip def recentWithNames(self, *names): """ See IChatterbox. """ names = set(names) for quip in self.recent(): if names & quip.names: yield quip def recentTags(self): """ See IChatterbox. """ tags = [] for quip in self.recent(): for tag in quip.tags: if tag not in tags: tags.append(tag) return tags def recentPrivate(self, user): """ See IChatterbox. """ for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [e[2] for e in quip.__acl__] if user in allowed: yield quip def recentCorrespondents(self, user): """ See IChatterbox. """ correspondents = {} for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [] conversed = False for acl in quip.__acl__: if acl[2] == user: conversed = True continue if acl[0] != 'Deny': allowed.append(acl[2]) if not allowed or not conversed: continue if allowed[0] not in correspondents: correspondents[allowed[0]] = { 'timeago': quip.created, 'summary': quip.text[:40] } return correspondents def recentConversations(self, user, correspondent): """ See IChatterbox. """ for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [e[2] for e in quip.__acl__] if user in allowed and correspondent in allowed: yield quip def recentInReplyTo(self, quipid): """ See IChatterbox. """ for quip in self.recent(): if quip.reply == quipid: yield quip def recentWithMatch(self, query): """ See IChatterbox. """ query = query.replace('*', '.*') patterns = [(word, re.compile("\\b%s\\b" % word, re.IGNORECASE)) for word in shlex.split(query.encode('utf-8'))] for quip in self.recent(): match_expr = query.replace('"', '') fallback_and = True for word, pattern in patterns: if word in ['and', 'or', 'not']: continue if pattern.search(quip.text): match_expr = match_expr.replace(word, 'True') else: match_expr = match_expr.replace(word, 'False') fallback_and = False try: match = eval(match_expr, {'__builtins__': { 'True': True, 'False': False }}) except SyntaxError: match = fallback_and if match: yield quip
def __init__(self): self._stack = AppendStack()
def __init__(self, user=None): self.users = AppendStack() self._count = 0 if user: self.users.push(user) self._count += 1
def __init__(self): self._stack = AppendStack(APPENDSTACK_MAX_LAYERS, APPENDSTACK_MAX_LENGTH)
class Chatterbox(Persistent): implements(IChatterbox) def __init__(self): self._quips = OOBTree() self._followed = OOBTree() self._followed_tags = OOBTree() # AppendStack defaults seem too low for search to make sense self._recent = AppendStack(max_layers=20, max_length=500) self._archive = Archive() def __iter__(self): return iter(self._quips) def __len__(self): """ See IChatterbox. """ return len(self._quips) def __getitem__(self, key): """ See IChatterbox. """ return self._quips[key] def addQuip(self, text, creator, repost=None, reply=None): """ See IChatterbox. """ quip = Quip(text, creator, repost, reply) sha = hashlib.sha512(text) sha.update(creator) sha.update(quip.created.isoformat()) key = sha.hexdigest() self._quips[key] = quip quip.__name__ = key quip.__parent__ = self self._recent.push(quip, self._archive.addLayer) return key def listFollowed(self, userid): """ See IChatterbox. """ return self._followed.get(userid, ()) def setFollowed(self, userid, followed): """ See IChatterbox. """ self._followed[userid] = tuple(followed) def listFollowedTags(self, userid): """ See IChatterbox. """ return self._followed_tags.get(userid, ()) def setFollowedTags(self, userid, followed_tags): """ See IChatterbox. """ self._followed_tags[userid] = tuple(followed_tags) def listFollowing(self, userid): """ See IChatterbox. """ for name, following in self._followed.items(): if userid in following: yield name def recent(self): """ See IChatterbox. """ for gen, index, quip in self._recent: yield quip def recentFollowed(self, userid): """ See IChatterbox. """ creators = (userid,) + self.listFollowed(userid) tags = set(self.listFollowedTags(userid)) names = set(creators) for quip in self.recent(): if quip.creator in creators or tags & quip.tags: yield quip def recentFollowedTags(self, userid): """ See IChatterbox. """ tags = set(self.listFollowedTags(userid)) for quip in self.recent(): if tags & quip.tags: yield quip def recentWithTag(self, tag): """ See IChatterbox. """ for quip in self.recent(): if tag in quip.tags: yield quip def recentWithCommunities(self, *communities): """ See IChatterbox. """ communities = set(communities) for quip in self.recent(): if communities & quip.communities: yield quip def recentWithCreators(self, *creators): """ See IChatterbox. """ names = set(creators) for quip in self.recent(): if quip.creator in creators: yield quip def recentWithNames(self, *names): """ See IChatterbox. """ names = set(names) for quip in self.recent(): if names & quip.names: yield quip def recentTags(self): """ See IChatterbox. """ tags = [] for quip in self.recent(): for tag in quip.tags: if tag not in tags: tags.append(tag) return tags def recentPrivate(self, user): """ See IChatterbox. """ for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [e[2] for e in quip.__acl__] if user in allowed: yield quip def recentCorrespondents(self, user): """ See IChatterbox. """ correspondents = {} for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [] conversed = False for acl in quip.__acl__: if acl[2] == user: conversed = True continue if acl[0] != 'Deny': allowed.append(acl[2]) if not allowed or not conversed: continue if allowed[0] not in correspondents: correspondents[allowed[0]] = {'timeago': quip.created, 'summary': quip.text[:40]} return correspondents def recentConversations(self, user, correspondent): """ See IChatterbox. """ for quip in self.recent(): if not bool(getattr(quip, '__acl__', ())): continue allowed = [e[2] for e in quip.__acl__] if user in allowed and correspondent in allowed: yield quip def recentInReplyTo(self, quipid): """ See IChatterbox. """ for quip in self.recent(): if quip.reply == quipid: yield quip def recentWithMatch(self, query): """ See IChatterbox. """ query = query.replace('*', '.*') patterns = [(word, re.compile("\\b%s\\b" % word, re.IGNORECASE)) for word in shlex.split(query.encode('utf-8'))] for quip in self.recent(): match_expr = query.replace('"', '') fallback_and = True for word, pattern in patterns: if word in ['and', 'or', 'not']: continue if pattern.search(quip.text): match_expr = match_expr.replace(word, 'True') else: match_expr = match_expr.replace(word, 'False') fallback_and = False try: match = eval(match_expr, {'__builtins__': {'True': True, 'False': False}}) except SyntaxError: match = fallback_and if match: yield quip