Exemple #1
0
    def getInfo(self):
        actor = self.flatten()
        if self.has_field_permission('talkingIn', 'view'):
            actor.setdefault('talkingIn', [])

            if actor['talkingIn']:
                conversation_objectids = [ObjectId(conv['id']) for conv in actor['talkingIn']]
                conversations_collection = MADMaxCollection(self.request, 'conversations')
                conversations = conversations_collection.search({'_id': {'$in': conversation_objectids}})
                conversations_by_id = {str(conv['_id']): conv for conv in conversations}

                messages_collection = MADMaxCollection(self.request, 'messages').collection

                pipeline = [
                    {"$match": {"contexts.id": {"$in": conversations_by_id.keys()}}},
                    {"$sort": {"_id": 1}},
                    {"$group": {
                        "_id": "$contexts.id",
                        "object": {"$last": "$object"},
                        "published": {"$last": "$published"}
                    }}
                ]
                messages = messages_collection.aggregate(pipeline)['result']

                def format_message(db_message):
                    message_object = db_message.get('object', {})
                    message = dict(
                        objectType=message_object.get('objectType', 'note'),
                        content=message_object.get('content', ''),
                        published=db_message.get('published', '')
                    )

                    if isinstance(message['published'], datetime.datetime):
                        try:
                            message['published'] = message['published'].isoformat()
                        except:
                            message['published'] = message['published']

                    # Set object urls for media types
                    if message['objectType'] in ['file', 'image']:
                        message['fullURL'] = message_object.get('fullURL', '')
                        if message['objectType'] == 'image':
                            message['thumbURL'] = message_object.get('thumbURL', '')

                    return message
                messages_by_conversation = {message['_id'][0]: format_message(message) for message in messages}
                for subscription in actor['talkingIn']:
                    conversation_object = conversations_by_id[subscription['id']]
                    subscription['displayName'] = conversation_object.realDisplayName(self['username'])
                    subscription['lastMessage'] = messages_by_conversation[subscription['id']]
                    subscription['participants'] = conversation_object['participants']
                    subscription['tags'] = conversation_object['tags']
                    subscription['messages'] = 0

                actor['talkingIn'] = sorted(actor['talkingIn'], reverse=True, key=lambda conv: conv['lastMessage']['published'])

        return actor
Exemple #2
0
    def removeUserSubscriptions(self, users_to_delete=[]):
        """
            Removes all users subscribed to the context, or only specifiyed
            user if userd_to_delete is provided
        """
        usersdb = MADMaxCollection(self.request, "users")
        criteria = {"{}.{}".format(self.user_subscription_storage, self.unique.lstrip("_")): self.getIdentifier()}
        users = usersdb.search(criteria)

        for user in users:
            if users_to_delete == [] or user["username"] in users_to_delete:
                user.removeSubscription(self)
Exemple #3
0
    def get_tokens(self, platform=None):
        """
            Returns all the tokens from a user, filtered by platform if any
        """

        tokens = MADMaxCollection(self.request, 'tokens')
        query = {
            '_owner': self['_owner'],
        }

        if platform is not None:
            query['platform'] = platform

        user_tokens = tokens.search(query)

        result = []
        for token in user_tokens:
            result.append(dict(token=token['token'], platform=token['platform'], username=token['_owner']))

        return result
Exemple #4
0
def subscribe(context, request):
    """
        /people/{username}/subscriptions
    """
    # XXX For now only one context can be subscribed at a time
    actor = request.actor
    rest_params = {'actor': actor,
                   'verb': 'subscribe'}

    # Initialize a Activity object from the request
    newactivity = Activity()
    newactivity.fromRequest(request, rest_params=rest_params)

    #Check if user is already subscribed
    subscribed_contexts_hashes = [a['urlHash'] for a in actor.subscribedTo['items']]
    if sha1(newactivity.object['url']).hexdigest() in subscribed_contexts_hashes:
        # If user already subscribed, send a 200 code and retrieve the original subscribe activity
        # post when user was susbcribed. This way in th return data we'll have the date of subscription
        code = 200
        activities = MADMaxCollection(context.db.activity)
        query = {'verb': 'subscribe', 'object.url': newactivity.object['url'], 'actor.username': actor.username}
        newactivity = activities.search(query)[-1]  # Pick the last one, so we get the last time user subscribed (in case a unsbuscription occured sometime...)

    else:
        # If user wasn't created, 201 indicates that the subscription has just been added
        code = 201
        newactivity_oid = newactivity.insert()  # Insert a subscribe activity
        newactivity['_id'] = newactivity_oid

        #Register subscription to the actor
        contexts = MADMaxCollection(context.db.contexts, query_key='urlHash')
        scontext = contexts[sha1(newactivity['object']['url']).hexdigest()]
        actor.addSubscription(scontext)

    handler = JSONResourceEntity(newactivity.flatten(), status_code=code)
    return handler.buildResponse()
Exemple #5
0
def processTweet(twitter_username, content, tweetID='---'):
    """ Process inbound tweet
    """
    logger.info("(INFO) Processing tweet %s from @%s with content: %s" % (str(tweetID), twitter_username, content))

    conn = pymongo.Connection(mongodb_url)
    db = conn[mongodb_db_name]
    users = MADMaxCollection(db.users)
    contexts = MADMaxCollection(db.contexts)

    contexts_with_twitter_username = contexts.search({"twitterUsernameId": {"$exists": True}})
    readable_follow_list = [users_to_follow.get('twitterUsername', '').lower() for users_to_follow in contexts_with_twitter_username]
    twitter_username = twitter_username.lower()
    # If we have a tweet from a followed user
    if twitter_username in readable_follow_list:
        # Find the context
        maxcontext = contexts.search({"twitterUsername": twitter_username})

        # Watch for the case when two or more context share twitterUsername
        for context in maxcontext:
            url_hash = context.get("urlHash")
            context_url = context.get("url")

            # Construct the payload with the activity information
            newactivity = {
                "object": {
                    "objectType": "note",
                    "content": content
                },
                "contexts": [
                    context_url,
                ],
                "generator": twitter_generator_name
            }

            re = requests.post('%s/admin/contexts/%s/activities' % (max_server_url, url_hash), json.dumps(newactivity), auth=('admin', 'admin'), verify=False)
            if re.status_code == 201:
                # 200: Successful tweet from context
                logger.info("(201) Successfully posted tweet %s from @%s as context %s" % (str(tweetID), twitter_username, context_url))
                return "(201) %s tweet from context %s" % (twitter_username, context_url)
            else:
                # 500: Error accessing the MAX API
                logger.info("(404) Discarding tweet %s from @%s : There's no MAX user with that twitter username." % (str(tweetID), twitter_username))
                return "(404) No Such Max User"

        return "Should not see me..."

    # If we have a tweet from a tracked hashtag
    # Parse text and determine the second or nth hashtag
    possible_hastags = findHashtags(content)
    # Prepare query with normalized possible_hastags

    query = [dict(twitterHashtag=hashtag.lower()) for hashtag in possible_hastags]

    if debug_hashtag in possible_hastags:
        logger.info("%s Debug hashtag detected!" % content)
        return "%s Debug hashtag detected! %s" % content

    # Check if twitter_username is a registered for a valid MAX username
    # if not, discard it
    maxuser = users.search({"twitterUsername": twitter_username})
    if maxuser:
        maxuser = maxuser[0]
    else:
        logger.info("(404) Discarding tweet %s from @%s : There's no MAX user with that twitter username." % (str(tweetID), twitter_username))
        return "(404) %s: No such MAX user." % twitter_username

    # Check if hashtag is registered for a valid MAX context
    # if not, discard it
    successful_tweets = 0
    maxcontext = contexts.search({"$or": query})
    if maxcontext:
        for context in maxcontext:
            # Check if MAX username has permission to post to the MAX context
            # if not, discard it
            try:
                can_write = canWriteInContexts(maxuser, [context.url])
            except:
                can_write = False
                logger.info("(401) Failure posting tweet %s: User %s can't write to %s" % (str(tweetID), maxuser.username, context['url']))

            if can_write:

                # Construct the payload with the activity information
                newactivity = {
                    "object": {
                        "objectType": "note",
                        "content": content
                    },
                    "contexts": [
                        context.url,
                    ],
                    "generator": twitter_generator_name
                }

                # Use the restricted REST endpoint for create a new activity in the specified
                # MAX context in name of the specified MAX username
                re = requests.post('%s/admin/people/%s/activities' % (max_server_url, maxuser.username), json.dumps(newactivity), auth=('admin', 'admin'), verify=False)
                if re.status_code == 201:
                    logger.info("(201) Successfully posted tweet %s from @%s as %s on context %s" % (str(tweetID), twitter_username, maxuser['username'], context.url))
                    successful_tweets += 1
                    #return "(201) Successful tweet from user %s in context %s" % (maxuser, context.url)
                else:
                    logger.info("(500) Error accessing the MAX API at %s" % max_server_url)
                    #return "(500) MAX API error"

        error_message = len(maxcontext) != successful_tweets and " We weren't able to send the tweet to all contexts. See above for more information." or ""
        logger.info("(INFO) Processed tweet %s to %d of %d possible contexts.%s" % (str(tweetID), successful_tweets, len(maxcontext), error_message))
        if error_message:
            return "(401) Some posts not sent"
        else:
            return "(200) All posts sent"
    else:
        logger.info("(404) Discarding tweet %s from @%s: There are no MAX context with any of those hashtags" % (str(tweetID), twitter_username))
        return "(404) %s: Not such MAX context %s" % (maxuser.username, maxcontext)

    return "Should not see mee"
Exemple #6
0
def processTweet(twitter_username, content, tweetID='---'):
    """ Process inbound tweet
    """
    logger.info("(INFO) Processing tweet %s from @%s with content: %s" %
                (str(tweetID), twitter_username, content))

    conn = pymongo.Connection(mongodb_url)
    db = conn[mongodb_db_name]
    users = MADMaxCollection(db.users)
    contexts = MADMaxCollection(db.contexts)

    contexts_with_twitter_username = contexts.search(
        {"twitterUsernameId": {
            "$exists": True
        }})
    readable_follow_list = [
        users_to_follow.get('twitterUsername', '').lower()
        for users_to_follow in contexts_with_twitter_username
    ]
    twitter_username = twitter_username.lower()
    # If we have a tweet from a followed user
    if twitter_username in readable_follow_list:
        # Find the context
        maxcontext = contexts.search({"twitterUsername": twitter_username})

        # Watch for the case when two or more context share twitterUsername
        for context in maxcontext:
            url_hash = context.get("urlHash")
            context_url = context.get("url")

            # Construct the payload with the activity information
            newactivity = {
                "object": {
                    "objectType": "note",
                    "content": content
                },
                "contexts": [
                    context_url,
                ],
                "generator": twitter_generator_name
            }

            re = requests.post('%s/admin/contexts/%s/activities' %
                               (max_server_url, url_hash),
                               json.dumps(newactivity),
                               auth=('admin', 'admin'),
                               verify=False)
            if re.status_code == 201:
                # 200: Successful tweet from context
                logger.info(
                    "(201) Successfully posted tweet %s from @%s as context %s"
                    % (str(tweetID), twitter_username, context_url))
                return "(201) %s tweet from context %s" % (twitter_username,
                                                           context_url)
            else:
                # 500: Error accessing the MAX API
                logger.info(
                    "(404) Discarding tweet %s from @%s : There's no MAX user with that twitter username."
                    % (str(tweetID), twitter_username))
                return "(404) No Such Max User"

        return "Should not see me..."

    # If we have a tweet from a tracked hashtag
    # Parse text and determine the second or nth hashtag
    possible_hastags = findHashtags(content)
    # Prepare query with normalized possible_hastags

    query = [
        dict(twitterHashtag=hashtag.lower()) for hashtag in possible_hastags
    ]

    if debug_hashtag in possible_hastags:
        logger.info("%s Debug hashtag detected!" % content)
        return "%s Debug hashtag detected! %s" % content

    # Check if twitter_username is a registered for a valid MAX username
    # if not, discard it
    maxuser = users.search({"twitterUsername": twitter_username})
    if maxuser:
        maxuser = maxuser[0]
    else:
        logger.info(
            "(404) Discarding tweet %s from @%s : There's no MAX user with that twitter username."
            % (str(tweetID), twitter_username))
        return "(404) %s: No such MAX user." % twitter_username

    # Check if hashtag is registered for a valid MAX context
    # if not, discard it
    successful_tweets = 0
    maxcontext = contexts.search({"$or": query})
    if maxcontext:
        for context in maxcontext:
            # Check if MAX username has permission to post to the MAX context
            # if not, discard it
            try:
                can_write = canWriteInContexts(maxuser, [context.url])
            except:
                can_write = False
                logger.info(
                    "(401) Failure posting tweet %s: User %s can't write to %s"
                    % (str(tweetID), maxuser.username, context['url']))

            if can_write:

                # Construct the payload with the activity information
                newactivity = {
                    "object": {
                        "objectType": "note",
                        "content": content
                    },
                    "contexts": [
                        context.url,
                    ],
                    "generator": twitter_generator_name
                }

                # Use the restricted REST endpoint for create a new activity in the specified
                # MAX context in name of the specified MAX username
                re = requests.post('%s/admin/people/%s/activities' %
                                   (max_server_url, maxuser.username),
                                   json.dumps(newactivity),
                                   auth=('admin', 'admin'),
                                   verify=False)
                if re.status_code == 201:
                    logger.info(
                        "(201) Successfully posted tweet %s from @%s as %s on context %s"
                        % (str(tweetID), twitter_username, maxuser['username'],
                           context.url))
                    successful_tweets += 1
                    #return "(201) Successful tweet from user %s in context %s" % (maxuser, context.url)
                else:
                    logger.info("(500) Error accessing the MAX API at %s" %
                                max_server_url)
                    #return "(500) MAX API error"

        error_message = len(
            maxcontext
        ) != successful_tweets and " We weren't able to send the tweet to all contexts. See above for more information." or ""
        logger.info(
            "(INFO) Processed tweet %s to %d of %d possible contexts.%s" %
            (str(tweetID), successful_tweets, len(maxcontext), error_message))
        if error_message:
            return "(401) Some posts not sent"
        else:
            return "(200) All posts sent"
    else:
        logger.info(
            "(404) Discarding tweet %s from @%s: There are no MAX context with any of those hashtags"
            % (str(tweetID), twitter_username))
        return "(404) %s: Not such MAX context %s" % (maxuser.username,
                                                      maxcontext)

    return "Should not see mee"