def run(nextPageID, currentPageID, username, followedByUsername, filterTags, filterAbout, additionalTags): api = SecureCommentAPI(session.auth.user) try: comments = api.getForObject( about, username=username, followedByUsername=followedByUsername, filterTags=filterTags, filterAbout=filterAbout, limit=26, olderThan=nextPageID, newerThan=currentPageID, additionalTags=additionalTags) except UnknownPathError as error: raise JSONRPCError("Unknown path in additionalTags: '%s'." % error.paths[0].encode('utf-8')) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return { 'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments }
def setUp(self): super(SecureCommentAPIWithUserRoleTest, self).setUp() createSystemData() UserAPI().create([ (u'username', u'password', u'User', u'*****@*****.**'), (u'fluidinfo.com', u'secret', u'Fluidinfo', u'*****@*****.**')]) self.user = getUser(u'username') self.comments = SecureCommentAPI(self.user)
def run(nextPageID, currentPageID): api = SecureCommentAPI(session.auth.user) comments = api.getAllFollowed(username, limit=26, olderThan=nextPageID, newerThan=currentPageID) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return {'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments}
def run(nextPageID, objectType): api = SecureCommentAPI(session.auth.user) result = api.getFollowedObjects(username, limit=21, olderThan=nextPageID, objectType=objectType) objects = [{'about': followedObject['about'], 'following': followedObject['following']} for followedObject in result] nextPageID = None if len(result) == 21: nextPageID = result[-2][u'creationTime'] objects = objects[:-1] return {'nextPageID': nextPageID, 'objects': objects}
def run(nextPageID, objectType): api = SecureCommentAPI(session.auth.user) result = api.getFollowedObjects(username, limit=21, olderThan=nextPageID, objectType=objectType) objects = [{ 'about': followedObject['about'], 'following': followedObject['following'] } for followedObject in result] nextPageID = None if len(result) == 21: nextPageID = result[-2][u'creationTime'] objects = objects[:-1] return {'nextPageID': nextPageID, 'objects': objects}
def run(nextPageID, currentPageID, filterTags, additionalTags): api = SecureCommentAPI(session.auth.user) comments = api.getRecent(limit=26, olderThan=nextPageID, newerThan=currentPageID, filterTags=filterTags, additionalTags=additionalTags) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return {'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments}
def upload(self, comments, message=None): """Upload batch comment data directly into Fluidinfo. @param comments: A C{list} of comment C{dict}s, each with keys: about: (Optional) A C{list} of C{unicode} values the comment is about. importer: The C{unicode} name of the importer application. text: The C{unicode} text of the comment. timestamp: A C{datetime.datetime} instance or C{None} if the current time should be used. url: A C{str} URL where the comment took place, or C{None}. username: The user's C{unicode} name in Fluidinfo. Note that the user might not officially exist in Fluidinfo yet. For example, we could be importing the tweets of someone who is followed by an actual Fluidinfo user. @param message: An optional C{unicode} message used to make logging output less generic. """ message = (u'%s: ' % message) if message else u'' nComments = len(comments) nImported = 0 logging.info('%sImporting %d new comments.', message, nComments) startTime = time() while comments: # NOTE: Be careful here. An obvious refactoring, at first # glance, is to move the logic to get the user and create the # comment API outside the loop, but doing so will cause the # user object to be used across transaction boundaries, which # we don't want to do. It's important that the database # interactions for each batch processed here are managed in a # single transaction. thisBatch = comments[0:min(len(comments), self._batchSize)] try: user = getUser(u'fluidinfo.com') if user is None: raise UnknownUserError([u'fluidinfo.com']) for comment in thisBatch: SecureCommentAPI(user).create(comment['text'], comment['username'], importer=comment['importer'], url=comment['url'], about=comment.get('about'), when=comment['timestamp']) transaction.commit() nImported += len(thisBatch) logging.info('%sImported %d/%d new comments.', message, nImported, nComments) except: transaction.abort() logging.info('%sImport failed. Aborting.', message) raise else: comments = comments[len(thisBatch):] elapsed = time() - startTime logging.info( '%sImported %d comments in %s seconds, %.3f ' 'comments/second.', message, nComments, elapsed, float(nComments) / elapsed)
def run(nextPageID, currentPageID): api = SecureCommentAPI(session.auth.user) comments = api.getAllFollowed(username, limit=26, olderThan=nextPageID, newerThan=currentPageID) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return { 'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments }
def run(nextPageID, currentPageID, filterTags, additionalTags): api = SecureCommentAPI(session.auth.user) comments = api.getRecent(limit=26, olderThan=nextPageID, newerThan=currentPageID, filterTags=filterTags, additionalTags=additionalTags) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return { 'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments }
def testCreateIsDenied(self): """ L{SecureObjectAPI.create} raises a L{PermissionDeniedError} if it's invoked by a L{User} with the L{Role.ANONYMOUS}. """ commentAPI = SecureCommentAPI(self.anon) error = self.assertRaises(PermissionDeniedError, commentAPI.create, 'text...', 'joe') self.assertEqual(self.anon.username, error.username) self.assertEqual( [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)], error.pathsAndOperations)
def testUpdateWithAnonymous(self): """ L{SecureObjectAPI.update} raises a L{PermissionDeniedError} if it's invoked by a L{User} with the L{Role.ANONYMOUS}. """ commentAPI = SecureCommentAPI(self.anon) error = self.assertRaises(PermissionDeniedError, commentAPI.update, 'digg.com', 'joe', datetime.utcnow(), u'new') self.assertEqual(self.anon.username, error.username) self.assertEqual( [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)], error.pathsAndOperations)
def run(nextPageID, currentPageID, username, followedByUsername, filterTags, filterAbout, additionalTags): api = SecureCommentAPI(session.auth.user) try: comments = api.getForObject(about, username=username, followedByUsername= followedByUsername, filterTags=filterTags, filterAbout=filterAbout, limit=26, olderThan=nextPageID, newerThan=currentPageID, additionalTags=additionalTags) except UnknownPathError as error: raise JSONRPCError("Unknown path in additionalTags: '%s'." % error.paths[0].encode('utf-8')) nextPageID = None if len(comments) == 26: nextPageID = comments[-2][u'fluidinfo.com/info/timestamp'] comments = comments[:-1] currentPageID = (comments[0][u'fluidinfo.com/info/timestamp'] if comments else None) return {'currentPageID': currentPageID, 'nextPageID': nextPageID, 'comments': comments}
def run(): api = SecureCommentAPI(session.auth.user) return api.summarizeObject(about)
def run(): api = SecureCommentAPI(session.auth.user) return api.create(text, session.auth.username, about=about, when=creationTime)
def run(importer, username, when, newText): api = SecureCommentAPI(session.auth.user) return api.update(importer, username, when, newText)
def run(importer, username, when): api = SecureCommentAPI(session.auth.user) return {'deletedComments': api.delete(importer, username, when)}
class SecureCommentAPIWithUserRoleTest(CommentAPITestMixin, FluidinfoTestCase): resources = [('cache', CacheResource()), ('config', ConfigResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(SecureCommentAPIWithUserRoleTest, self).setUp() createSystemData() UserAPI().create([ (u'username', u'password', u'User', u'*****@*****.**'), (u'fluidinfo.com', u'secret', u'Fluidinfo', u'*****@*****.**')]) self.user = getUser(u'username') self.comments = SecureCommentAPI(self.user) def testCreateSucceeds(self): """ L{SecureCommentAPI.create} returns a C{dict} with the expected keys and values. """ when = datetime.utcnow() floatTime = timegm(when.utctimetuple()) + float(when.strftime('0.%f')) isoTime = when.isoformat() result = self.comments.create(u'Comment text', u'username', when=when) expected = { 'fluidinfo.com/info/about': [], 'fluidinfo.com/info/text': u'Comment text', 'fluidinfo.com/info/timestamp': floatTime, 'fluidinfo.com/info/url': ( 'https://fluidinfo.com/comment/fluidinfo.com/username/' + isoTime), 'fluidinfo.com/info/username': u'username', } self.assertEqual(expected, result) def testDeleteAnotherUsersComment(self): """ L{SecureObjectAPI.delete} raises a L{PermissionDeniedError} if a L{User} tries to delete a comment made by someone else. """ error = self.assertRaises(PermissionDeniedError, self.comments.delete, 'digg.com', 'joe', datetime.utcnow()) self.assertEqual(u'username', error.username) self.assertEqual( [(u'fluidinfo.com/info/username', Operation.DELETE_TAG_VALUE)], error.pathsAndOperations) def testUpdateAnotherUsersComment(self): """ L{SecureObjectAPI.update} raises a L{PermissionDeniedError} if a L{User} tries to update a comment made by someone else. """ error = self.assertRaises(PermissionDeniedError, self.comments.update, 'digg.com', 'joe', datetime.utcnow(), u'new') self.assertEqual(u'username', error.username) self.assertEqual( [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)], error.pathsAndOperations) def testGetForObjectWithAdditionalTagsUnreadable(self): """ L{SecureCommentAPI.getForObject} raises a L{PermissionDeniedError} if a L{User} tries to retrieve C{additionalTags} which are unreadable to them. """ objectID = uuid4() values = {objectID: {u'username/tag': 16}} SecureTagValueAPI(self.user).set(values) CachingPermissionAPI(self.user).set([(u'username/tag', Operation.READ_TAG_VALUE, Policy.CLOSED, [])]) error = self.assertRaises(PermissionDeniedError, self.comments.getForObject, u'about', additionalTags=[u'username/tag']) self.assertEqual(u'username', error.username) self.assertEqual( [(u'username/tag', Operation.READ_TAG_VALUE)], error.pathsAndOperations) def testGetForObjectWithAdditionalTagsNonexistent(self): """ L{SecureCommentAPI.getForObject} raises a L{PermissionDeniedError} if a L{User} tries to retrieve C{additionalTags} which are unreadable to them. """ self.assertRaises(UnknownPathError, self.comments.getForObject, u'about', additionalTags=[u'user/nonexistent']) def testGetForUserWithAdditionalTagsUnreadable(self): """ L{SecureCommentAPI.getForUser} raises a L{PermissionDeniedError} if a L{User} tries to retrieve C{additionalTags} which are unreadable to them. """ objectID = uuid4() values = {objectID: {u'username/tag': 16}} SecureTagValueAPI(self.user).set(values) CachingPermissionAPI(self.user).set([(u'username/tag', Operation.READ_TAG_VALUE, Policy.CLOSED, [])]) error = self.assertRaises(PermissionDeniedError, self.comments.getForUser, u'username', additionalTags=[u'username/tag']) self.assertEqual(u'username', error.username) self.assertEqual( [(u'username/tag', Operation.READ_TAG_VALUE)], error.pathsAndOperations) def testGetForUserWithAdditionalTagsNonexistent(self): """ L{SecureCommentAPI.getForUser} raises a L{PermissionDeniedError} if a L{User} tries to retrieve C{additionalTags} which are unreadable to them. """ self.assertRaises(UnknownPathError, self.comments.getForUser, u'username', additionalTags=[u'user/nonexistent'])