Exemple #1
0
def add_comment(thread_uid, author, text):
    """Add comment to specefied thread.

    :param thread_uid: Thread unique ID.
    :param author: Author of comment.
    :param text: Comment text.
    """
    # Setup new UID for comment
    comment_uid = uid()

    # Store comment metadata and rewrite data about last comment for thread
    with content.pipeline() as pipe:
        pipe.hmset(build_key(COMMENT_KEY, thread_uid, comment_uid), {
            'author': author,
            'text': text,
            'timestamp': time.time(),
        })
        pipe.hmset(build_key(THREAD_KEY, thread_uid), {
            'last_comment_uid': comment_uid,
        })
        pipe.execute()

    # Put comment to comments list and incr comments counter for thread
    with links.pipeline() as pipe:
        pipe.rpush(build_key(THREAD_COMMENTS_KEY, thread_uid), comment_uid)
        pipe.incr(build_key(THREAD_COUNTER_KEY, thread_uid))
        pipe.execute()

    # Comment added, everything is alright
    return True
Exemple #2
0
def list_comments(thread_uid):
    """List all comments for given thread.

    :param thread_uid: Thread unique UID.
    """
    with content.pipeline() as pipe:
        comments_key = build_key(THREAD_COMMENTS_KEY, thread_uid)
        uids = []
        for comment_uid in links.lrange(comments_key, 0, -1):
            pipe.hgetall(build_key(COMMENT_KEY, thread_uid, comment_uid))
            uids.append(comment_uid)
        return OrderedDict(zip(uids, pipe.execute()))
Exemple #3
0
def list_threads():
    """List all available threads in most efficient way."""
    def order(item):
        """Order Threads by latest comment or start time."""
        thread = item[1]
        timestamp = thread['timestamp']
        return thread.get('last_comment', {}).get('timestamp') or timestamp

    # Read Threads from Links and Content databases
    with content.pipeline() as pipe:
        uids = []
        for thread_uid in links.lrange(build_key(THREADS_KEY), 0, -1):
            pipe.hgetall(build_key(THREAD_KEY, thread_uid))
            uids.append(thread_uid)
        threads = dict(zip(uids, pipe.execute()))

    # Make another multi request for threads' counters and last comments where
    # possible
    comments_request = OrderedDict()

    for thread_uid, thread in iteritems(threads):
        last_comment_uid = thread.get('last_comment_uid')
        if not last_comment_uid:
            continue
        comments_request[thread_uid] = thread['last_comment_uid']

    # We assume that last comment and comments counter available only for
    # threads with comments
    if comments_request:
        with links.pipeline() as pipe:
            for thread_uid in iterkeys(comments_request):
                pipe.get(build_key(THREAD_COUNTER_KEY, thread_uid))
            response = zip(iterkeys(comments_request), pipe.execute())

        for thread_uid, counter in response:
            threads[thread_uid]['comments_counter'] = counter

        with content.pipeline() as pipe:
            for thread_uid, comment_uid in iteritems(comments_request):
                key = build_key(COMMENT_KEY, thread_uid, comment_uid)
                pipe.hgetall(key)
            response = zip(iterkeys(comments_request), pipe.execute())

        for thread_uid, comment in response:
            threads[thread_uid]['last_comment'] = comment

    return OrderedDict(sorted(iteritems(threads), key=order, reverse=True))
Exemple #4
0
def get_thread(thread_uid, last_comment=False, counter=False):
    """Read thread metadata by specefied UID.

    :param thread_uid: Thread unique ID.
    :param last_comment: Include last comment metadata or not?
    :param counter: Include comments counter or not?
    """
    thread = content.hgetall(build_key(THREAD_KEY, thread_uid))
    if not thread:
        return thread

    last_comment_uid = thread.get('last_comment_uid')
    if last_comment and last_comment_uid:
        comment_key = build_key(COMMENT_KEY, thread_uid, last_comment_uid)
        thread['last_comment'] = content.hgetall(comment_key)

    if counter:
        counter_key = build_key(THREAD_COUNTER_KEY, thread_uid)
        thread['comments_counter'] = links.get(counter_key)

    return thread
Exemple #5
0
def delete_thread(thread_uid):
    """Delete thread and all its data from storages.

    :param thread_uid: Thread unique ID.
    """
    pipe = content.pipeline()
    pipe.delete(build_key(THREAD_KEY, thread_uid))

    comments_key = build_key(THREAD_COMMENTS_KEY, thread_uid)
    for comment_uid in links.lrange(comments_key, 0, -1):
        pipe.delete(build_key(COMMENT_KEY, thread_uid, comment_uid))

    pipe.execute()

    with links.pipeline() as pipe:
        pipe.delete(comments_key)
        pipe.delete(build_key(THREAD_COUNTER_KEY, thread_uid))
        pipe.lrem(build_key(THREADS_KEY), 1, thread_uid)
        pipe.execute()

    return True
Exemple #6
0
def start_thread(author, subject, comment=None):
    """Start new thread with or without comment.

    :param author: Thread author.
    :param subject: Thread subject.
    :param comment: Text for first comment if any.
    """
    # Setup new UID for the Thread and add it to Links and Content storages
    thread_uid = uid()

    content.hmset(build_key(THREAD_KEY, thread_uid), {
        'author': author,
        'subject': subject,
        'timestamp': time.time(),
    })
    links.lpush(build_key(THREADS_KEY), thread_uid)

    # Add comment, but only if it not empty
    if comment:
        add_comment(thread_uid, author, comment)

    # Everything is OK
    return True
Exemple #7
0
 def create_or_update(self, ip):
     key = utils.build_key(ip)
     rkey = utils.build_reversed_key(ip)
     if (key in self.flows_stats) or (rkey in self.flows_stats):
         ## Existing flow
         fs = None
         if key in self.flows_stats:
             fs = self.flows_stats[key]
         else:
             fs = self.flows_stats[rkey]
         fs.update_stats(ip)
         self.update_traffic_stats(ip)
     elif utils.is_a_new_flow(ip):
         ## A new flow
         fs = flow_stats.FlowStats(ip)
         self.flows_stats[key] = fs
         self.create_or_update_context_stats(ip)
Exemple #8
0
def main():
    """Wipe all data from Links and Content storages."""
    start_time = time.time()
    print('Start deleting available Threads')

    with app.app_context():
        # Storage requires app in global context
        import storage

        for thread_uid, thread in iteritems(storage.list_threads()):
            storage.delete_thread(thread_uid)
            print('    Thread deleted! UID #{0}, subject: {1}'.
                  format(thread_uid, thread['subject']))

        storage.links.delete(build_key(THREADS_KEY))

    print('All Threads deleted. Done in {0:.4f}s'.
          format(time.time() - start_time))
    return False