def getForFollowedObjects(self, username, limit=20, olderThan=None, newerThan=None): """Get the comments made on all the objects followed by the given user. @param username: The user to get the comments for. @param limit: Optionally, The maximum number of comments to return. @param olderThan: Optionally a C{datetime} indicating to return only comments older than it. @param newerThan: A C{datetime} indicating to return only comments newer than it. @return: A C{list} of comments represented by a C{dict} with the following format:: { 'fluidinfo.com/info/about': <about-value-list>, 'fluidinfo.com/info/text': <comment-text>, 'fluidinfo.com/info/timestamp': <float-timestamp>, 'fluidinfo.com/info/url': <url>, 'fluidinfo.com/info/username': <username>, } """ followedObjectsResult = getObjectIDs([username + u'/follows']) subselect = followedObjectsResult.get_select_expr(TagValue.objectID) where = [ Comment.objectID == CommentObjectLink.commentID, CommentObjectLink.objectID.is_in(subselect) ] return self._findComments(where, limit, olderThan, newerThan)
def delete(self, paths): """Delete L{Tag}s matching C{paths}. L{TagValue}s and permissions associated with the deleted L{Tag}s are removed by cascading deletes in the database schema. @param paths: A sequence of L{Tag.path}s. @return: A C{list} of C{(objectID, Tag.path)} 2-tuples representing the L{Tag}s that were removed. """ if isgenerator(paths): paths = list(paths) result = getTags(paths=paths) deletedTagPaths = list(result.values(Tag.objectID, Tag.path)) # Delete the fluiddb/tags/description tag values stored for removed # tags. Associated TagValue's are removed by an ON DELETE CASCADE # trigger. self._factory.tagValues(self._user).delete( [(objectID, path) for objectID, _ in deletedTagPaths for path in [u'fluiddb/tags/description', u'fluiddb/tags/path']]) # Touch all the objects for the given tag paths. objectIDs = list(getObjectIDs(paths)) touchObjects(objectIDs) result.remove() return deletedTagPaths
def getForFollowedObjects(self, username, limit=20, olderThan=None, newerThan=None): """Get the comments made on all the objects followed by the given user. @param username: The user to get the comments for. @param limit: Optionally, The maximum number of comments to return. @param olderThan: Optionally a C{datetime} indicating to return only comments older than it. @param newerThan: A C{datetime} indicating to return only comments newer than it. @return: A C{list} of comments represented by a C{dict} with the following format:: { 'fluidinfo.com/info/about': <about-value-list>, 'fluidinfo.com/info/text': <comment-text>, 'fluidinfo.com/info/timestamp': <float-timestamp>, 'fluidinfo.com/info/url': <url>, 'fluidinfo.com/info/username': <username>, } """ followedObjectsResult = getObjectIDs([username + u'/follows']) subselect = followedObjectsResult.get_select_expr(TagValue.objectID) where = [Comment.objectID == CommentObjectLink.commentID, CommentObjectLink.objectID.is_in(subselect)] return self._findComments(where, limit, olderThan, newerThan)
def testGetObjectIDsWithUnknownObjectID(self): """ L{getObjectIDs} doesn't return any results if unknown tag paths are provided. """ user = createUser(u'user', u'secret', u'User', u'*****@*****.**') user.namespaceID = createNamespace(user, user.username, None).id tag = createTag(user, user.namespace, u'name1') createTagValue(user.id, tag.id, uuid4(), 42) self.assertEqual([], list(getObjectIDs([u'user/name2'])))
def testGetObjectIDs(self): """ L{getObjectIDs} returns a sequence of object IDs that match the specified paths. """ objectID1 = uuid4() user = createUser(u'user', u'secret', u'User', u'*****@*****.**') user.namespaceID = createNamespace(user, user.username, None).id tag1 = createTag(user, user.namespace, u'name1') tag2 = createTag(user, user.namespace, u'name2') createTagValue(user.id, tag1.id, objectID1, 42) createTagValue(user.id, tag2.id, uuid4(), 17) self.assertEqual(objectID1, getObjectIDs([u'user/name1']).one())
def delete(self, paths): """See L{TagAPI.delete}. Permissions for deleted L{Tag}s are removed from the cache. """ if isgenerator(paths): paths = list(paths) # FIXME getObjectIDs is called twice--once here and once in # TagAPI.delete. It would be better if we only did this once, not to # mention that this breaks encapsulation by bypassing the model layer # and accessing the data layer directly. -jkakar objectIDs = set(getObjectIDs(paths)) RecentObjectActivityCache().clear(objectIDs) usernames = set([path.split('/')[0] for path in paths]) RecentUserActivityCache().clear(usernames) PermissionCache().clearTagPermissions(paths) return self._api.delete(paths)
def getAllFollowed(self, username, limit=20, olderThan=None, newerThan=None): """ Get all the comments on the followed objects, by the followed users and by the requested user. @param username: The user to get the comments for. @param limit: Optionally, The maximum number of comments to return. @param olderThan: Optionally a C{datetime} indicating to return only comments older than it. @param newerThan: A C{datetime} indicating to return only comments newer than it. @return: A C{list} of comments represented by a C{dict} with the following format:: { 'fluidinfo.com/info/about': <about-value-list>, 'fluidinfo.com/info/text': <comment-text>, 'fluidinfo.com/info/timestamp': <float-timestamp>, 'fluidinfo.com/info/url': <url>, 'fluidinfo.com/info/username': <username>, } """ store = getMainStore() result = getObjectIDs([username + u'/follows']) objectsSubselect = result.get_select_expr(TagValue.objectID) result = store.find(User.username, User.objectID == TagValue.objectID, Tag.id == TagValue.tagID, Tag.path == username + u'/follows') usersSubselect = result.get_select_expr(User.username) where = [ Comment.objectID == CommentObjectLink.commentID, Or(CommentObjectLink.objectID.is_in(objectsSubselect), Comment.username.is_in(usersSubselect), Comment.username == username) ] if olderThan is not None: where.append(Comment.creationTime < olderThan) return self._findComments(where, limit, olderThan, newerThan)
def delete(self, paths): """See L{TagAPI.delete}. Permissions for deleted L{Tag}s are removed from the cache. """ if isgenerator(paths): paths = list(paths) # FIXME getObjectIDs is called twice--once here and once in # TagAPI.delete. It would be better if we only did this once, not to # mention that this breaks encapsulation by bypassing the model layer # and accessing the data layer directly. -jkakar objectIDs = set(getObjectIDs(paths)) RecentObjectActivityCache().clear(objectIDs) usernames = set([path.split('/')[0] for path in paths]) RecentUserActivityCache().clear(usernames) PermissionCache().clearTagPermissions(paths) return self._api.delete(paths)
def _resolveHasQueries(self, queries): """Find object IDs with a particular tag attached to them. @param queries: A list of L{Query} objects to resolve. @return: A C{dict} mapping L{Query}s sets of object IDs. """ results = {} for query in queries: path = query.rootNode.left.value if path == u'fluiddb/id': results[query] = SearchError( 'fluiddb/id is not supported in queries.') continue # FIXME: make limits consistent across all the code base. result = getObjectIDs([path]).config(limit=10000) results[query] = set(result) return results
def _resolveHasQueries(self, queries): """Find object IDs with a particular tag attached to them. @param queries: A list of L{Query} objects to resolve. @return: A C{dict} mapping L{Query}s sets of object IDs. """ results = {} for query in queries: path = query.rootNode.left.value if path == u'fluiddb/id': results[query] = SearchError( 'fluiddb/id is not supported in queries.') continue # FIXME: make limits consistent across all the code base. result = getObjectIDs([path]).config(limit=10000) results[query] = set(result) return results
def getAllFollowed(self, username, limit=20, olderThan=None, newerThan=None): """ Get all the comments on the followed objects, by the followed users and by the requested user. @param username: The user to get the comments for. @param limit: Optionally, The maximum number of comments to return. @param olderThan: Optionally a C{datetime} indicating to return only comments older than it. @param newerThan: A C{datetime} indicating to return only comments newer than it. @return: A C{list} of comments represented by a C{dict} with the following format:: { 'fluidinfo.com/info/about': <about-value-list>, 'fluidinfo.com/info/text': <comment-text>, 'fluidinfo.com/info/timestamp': <float-timestamp>, 'fluidinfo.com/info/url': <url>, 'fluidinfo.com/info/username': <username>, } """ store = getMainStore() result = getObjectIDs([username + u'/follows']) objectsSubselect = result.get_select_expr(TagValue.objectID) result = store.find(User.username, User.objectID == TagValue.objectID, Tag.id == TagValue.tagID, Tag.path == username + u'/follows') usersSubselect = result.get_select_expr(User.username) where = [Comment.objectID == CommentObjectLink.commentID, Or(CommentObjectLink.objectID.is_in(objectsSubselect), Comment.username.is_in(usersSubselect), Comment.username == username)] if olderThan is not None: where.append(Comment.creationTime < olderThan) return self._findComments(where, limit, olderThan, newerThan)
def testGetObjectIDsWithoutData(self): """ L{getObjectIDs} doesn't return any results if no paths are provided. """ self.assertEqual([], list(getObjectIDs([])))