# Path: channels/app.py
# def init_database(app):
# def init_disqus(app):
# def init_publisher(app):
# def get_client(key):
# 
# Path: channels/oauth.py
# def api_call(func, **kwargs):
#     access_token = get_access_token()
#     try:
#         if access_token:
#             result = func(access_token=access_token, **kwargs)
#         else:
#             result = func(**kwargs)
#     except InvalidAccessToken:
#         raise Logout
#     return result
# 
# Path: channels/utils.py
# def avatar_hash(user):
#     return md5('disqus:' + str(user['username'])).hexdigest()
# 
# def datestr_to_datetime(dt):
#     return datetime.strptime(dt, '%Y-%m-%dT%H:%M:%S')
# 
# def from_cache(callback, cache_key=None, expires=60):
#     if cache_key is None:
#         if hasattr(callback, 'im_self'):
#             cache_key = '.'.join([callback.__module__, callback.im_self.__name__, callback.__name__])
#         else:
#             cache_key = '%s.%s' % (callback.__module__, callback.__name__)
#     conn = db.get_conn(cache_key)
#     result = conn.get(cache_key)
#     if result:
#         try:
#             result = json.loads(result)
#         except Exception, e:
#             logger.exception(e)
#             result = None
# 
#     if result is None:
#         result = callback()
#         pipe = conn.pipeline()
#         pipe.set(cache_key, json.dumps(result))
#         pipe.expire(cache_key, 60)
#         pipe.execute()
#     return result
# 
# def secure_avatar(avatar_url):
#     return avatar_url.replace('http://mediacdn', 'https://securecdn')
# 
# Path: channels/views.py
# class Publisher(object):
# class View(object):
#     def __init__(self, client, buffer_size=10000):
#     def publish(self, key, value):
#     def __init__(self, redis, publisher, name, version=1):
#     def add(self, data, score, _key=None, **kwargs):
#     def add_to_set(self, id, score, _data=None, _key=None, **kwargs):
#     def incr_in_set(self, id, score, _data=None, _key=None, **kwargs):
#     def remove(self, data, _key=None, **kwargs):
#     def remove_from_set(self, id, _key=None, **kwargs):
#     def incr_counter(self, id, key, amount=1):
#     def get(self, id):
#     def get_many(self, id_list):
#     def list(self, offset=0, limit=-1, desc=True, _key=None, **kwargs):
#     def search(self, query, field, limit=100, desc=True, _key=None, **kwargs):
#     def get_key(self, keybase=None, **kwargs):
#     def get_channel_key(self, key):
#     def get_obj_key(self, id):


from datetime import datetime, timedelta
from disqusapi import Paginator
from flask import session
from channels.app import app, disqusapi, schedule
from channels.oauth import api_call
from channels.utils import avatar_hash, datestr_to_datetime, from_cache, secure_avatar
from channels.views import threads, posts, users
        thread_ids = []
        for talk in sorted(schedule.itervalues(), key=lambda x: (x['start'], x['room'])):
            if talk['end'] > start:  # and talk['start'] < end:
                thread_ids.append(talk['disqus:thread']['id'])
            if num > limit:
                return

        if not thread_ids:
            return []

        thread_ids = thread_ids[:limit]

        result = threads.get_many(thread_ids)
        missing_thread_ids = [t for t, v in result.iteritems() if not v]
        if missing_thread_ids:
            thread_list = disqusapi.threads.list(thread=missing_thread_ids, forum=app.config['DISQUS_FORUM'])
            for thread in thread_list:
                result[thread['id']] = Thread.save(thread)

        for thread in result.itervalues():
            if not thread:
                continue
            thread['session'] = schedule.get(thread.get('link'))

        return [result[t] for t in thread_ids if result.get(t)]


class Post:
    @classmethod
    def format(cls, post):

# Path: channels/app.py
# def init_database(app):
# def init_disqus(app):
# def init_publisher(app):
# def get_client(key):
# 
# Path: channels/oauth.py
# def api_call(func, **kwargs):
#     access_token = get_access_token()
#     try:
#         if access_token:
#             result = func(access_token=access_token, **kwargs)
#         else:
#             result = func(**kwargs)
#     except InvalidAccessToken:
#         raise Logout
#     return result
# 
# Path: channels/utils.py
# def avatar_hash(user):
#     return md5('disqus:' + str(user['username'])).hexdigest()
# 
# def datestr_to_datetime(dt):
#     return datetime.strptime(dt, '%Y-%m-%dT%H:%M:%S')
# 
# def from_cache(callback, cache_key=None, expires=60):
#     if cache_key is None:
#         if hasattr(callback, 'im_self'):
#             cache_key = '.'.join([callback.__module__, callback.im_self.__name__, callback.__name__])
#         else:
#             cache_key = '%s.%s' % (callback.__module__, callback.__name__)
#     conn = db.get_conn(cache_key)
#     result = conn.get(cache_key)
#     if result:
#         try:
#             result = json.loads(result)
#         except Exception, e:
#             logger.exception(e)
#             result = None
# 
#     if result is None:
#         result = callback()
#         pipe = conn.pipeline()
#         pipe.set(cache_key, json.dumps(result))
#         pipe.expire(cache_key, 60)
#         pipe.execute()
#     return result
# 
# def secure_avatar(avatar_url):
#     return avatar_url.replace('http://mediacdn', 'https://securecdn')
# 
# Path: channels/views.py
# class Publisher(object):
# class View(object):
#     def __init__(self, client, buffer_size=10000):
#     def publish(self, key, value):
#     def __init__(self, redis, publisher, name, version=1):
#     def add(self, data, score, _key=None, **kwargs):
#     def add_to_set(self, id, score, _data=None, _key=None, **kwargs):
#     def incr_in_set(self, id, score, _data=None, _key=None, **kwargs):
#     def remove(self, data, _key=None, **kwargs):
#     def remove_from_set(self, id, _key=None, **kwargs):
#     def incr_counter(self, id, key, amount=1):
#     def get(self, id):
#     def get_many(self, id_list):
#     def list(self, offset=0, limit=-1, desc=True, _key=None, **kwargs):
#     def search(self, query, field, limit=100, desc=True, _key=None, **kwargs):
#     def get_key(self, keybase=None, **kwargs):
#     def get_channel_key(self, key):
#     def get_obj_key(self, id):


# Path: channels/models.py
from datetime import datetime, timedelta
from disqusapi import Paginator
from flask import session
from channels.app import app, disqusapi, schedule
from channels.oauth import api_call
from channels.utils import avatar_hash, datestr_to_datetime, from_cache, secure_avatar
from channels.views import threads, posts, users

        thread_ids = []
        for talk in sorted(schedule.itervalues(), key=lambda x: (x['start'], x['room'])):
            if talk['end'] > start:  # and talk['start'] < end:
                thread_ids.append(talk['disqus:thread']['id'])
            if num > limit:
                return

        if not thread_ids:
            return []

        thread_ids = thread_ids[:limit]

        result = threads.get_many(thread_ids)
        missing_thread_ids = [t for t, v in result.iteritems() if not v]
        if missing_thread_ids:
            thread_list = disqusapi.threads.list(thread=missing_thread_ids, forum=app.config['DISQUS_FORUM'])
            for thread in thread_list:
                result[thread['id']] = Thread.save(thread)

        for thread in result.itervalues():
            if not thread:
                continue
            thread['session'] = schedule.get(thread.get('link'))

        return [result[t] for t in thread_ids if result.get(t)]


class Post:
    @classmethod
    def format(cls, post):

        avatar = secure_avatar(post['author']['avatar']['cache'])