# Path: henet/comments.py
# class ArticleThread(object):
#     def __init__(self, storage_dir, article_uuid=None, thread_uuid=None):
#         self.storage_dir = storage_dir
#         if article_uuid is None:
#             article_uuid = str(uuid4())
#         self.article_uuid = article_uuid
#         self.thread_uuid = thread_uuid
#         self.thread = None
#         hashed_uuid = hashlib.md5(self.article_uuid).hexdigest()
#         self.filename = os.path.join(self.storage_dir,
#                                      'article_' + hashed_uuid + '.rst')
#         self.load()
# 
#     def add_comment(self, *args, **kw):
#         return self.thread.add_comment(*args, **kw)
# 
#     def asjson(self):
#         comments = [comment.asjson() for comment in
#                     self.thread.get_comments()]
# 
#         return {'article_uuid': self.article_uuid,
#                 'thread_uuid': self.thread_uuid,
#                 'comments': comments}
# 
#     def save(self):
#         with open(self.filename, 'w') as f:
#             f.write(self.render().encode('utf8'))
#         self.thread.save()
# 
#     def load(self):
#         if not os.path.exists(self.filename):
#             self.thread = Thread(self.storage_dir, self.thread_uuid)
#             self.thread_uuid = self.thread.uuid
#         else:
#             with open(self.filename) as f:
#                 uuids = f.read().split(':')
#             self.article_uuid = uuids[0]
#             self.thread_uuid = uuids[1]
#             self.thread = Thread(self.storage_dir, self.thread_uuid)
# 
#         self.thread.link_to_article(self.article_uuid)
# 
#     def render(self):
#         return u'%s:%s' % (self.article_uuid, self.thread_uuid)
# 
#     @classmethod
#     def loadfromfile(cls, filename):
#         storage_dir = os.path.dirname(filename)
#         klass = ArticleThread(storage_dir)
#         klass.filename = filename
#         klass.load()
#         return klass
# 
# class CommentsDB(object):
#     def __init__(self, storage_dir):
#         self.storage_dir = storage_dir
#         if not os.path.exists(storage_dir):
#             os.makedirs(storage_dir)
# 
#     def _get_comment(self, uuid):
#         thread = comment = None
#         for file in os.listdir(self.storage_dir):
#             if not file.startswith('thread_'):
#                 continue
#             filename = os.path.join(self.storage_dir, file)
#             thread = Thread.loadfromfile(filename)
#             try:
#                 comment = thread.get_comment(uuid)
#                 break
#             except KeyError:
#                 pass
#         if comment is None:
#             thread = None
#         return thread, comment
# 
#     def activate_comment(self, uuid):
#         thread, comment = self._get_comment(uuid)
#         if thread is not None:
#             thread.activate_comment(comment.uuid)
#             thread.save()
# 
#     def reject_comment(self, uuid):
#         thread, comment = self._get_comment(uuid)
#         if thread is not None:
#             thread.reject_comment(comment.uuid)
#             thread.save()
# 
#     def _get_comments(self, inactive=True, active=False,
#                       article_uuid=None):
#         for file in os.listdir(self.storage_dir):
#             if not file.startswith('article_'):
#                 continue
#             filename = os.path.join(self.storage_dir, file)
#             article_thread = ArticleThread.loadfromfile(filename)
#             thread = article_thread.thread
# 
#             if (article_uuid is not None and
#                     article_thread.article_uuid != article_uuid):
#                 continue
# 
#             for comment in thread.get_comments(include_inactive=inactive,
#                                                include_active=active):
#                 yield comment
# 
#     def get_moderation_queue(self):
#         return self._get_comments()
# 
#     def get_comments(self, article_uuid=None):
#         return self._get_comments(inactive=False, active=True,
#                                   article_uuid=article_uuid)
# 
# Path: henet/events.py
# def emit(event, **data):
#     for subscriber in _SUBSCRIBERS[event]:
#         subscriber(event, **data)
#     for subscriber in _SUBSCRIBERS[ALL_EVENTS]:
#         subscriber(event, **data)
# 
# EVENT_CREATED_COMMENT = 3
# 
# Path: henet/rst/rst2html.py
# def rst2html(rst, theme=None, opts=None, body_only=False):
#     rst_opts = default_rst_opts.copy()
#     rst_opts['warning_stream'] = StringIO()
# 
#     if body_only:
#         out = publish_parts(rst, writer_name='html',
#                             settings_overrides=rst_opts)['html_body']
# 
#         rst_opts['warning_stream'].seek(0)
#         warnings = rst_opts['warning_stream'].read()
#         return out, warnings
# 
#     if opts:
#         rst_opts.update(opts)
#     rst_opts['template'] = os.path.join(THEMES, 'template.txt')
# 
#     stylesheets = ['basic.css']
#     if theme:
#         stylesheets.append('%s/%s.css' % (theme, theme))
#     rst_opts['stylesheet'] = ','.join([J(THEMES, p) for p in stylesheets])
# 
#     out = publish_string(rst, writer_name='html', settings_overrides=rst_opts)
# 
#     rst_opts['warning_stream'].seek(0)
#     warnings = rst_opts['warning_stream'].read()
#     return out, warnings


import datetime
from bottle import route, request, app, response, get, post, redirect
from bottle_utils.csrf import csrf_protect, csrf_token
from henet.comments import ArticleThread, CommentsDB
from henet.events import emit, EVENT_CREATED_COMMENT
from henet.rst.rst2html import rst2html
# encoding: utf8



def enable_cors(func):
    def _enable_cors(*args, **kwargs):
        hds = response.headers
        hds['Access-Control-Allow-Origin'] = '*'

# Path: henet/comments.py
# class ArticleThread(object):
#     def __init__(self, storage_dir, article_uuid=None, thread_uuid=None):
#         self.storage_dir = storage_dir
#         if article_uuid is None:
#             article_uuid = str(uuid4())
#         self.article_uuid = article_uuid
#         self.thread_uuid = thread_uuid
#         self.thread = None
#         hashed_uuid = hashlib.md5(self.article_uuid).hexdigest()
#         self.filename = os.path.join(self.storage_dir,
#                                      'article_' + hashed_uuid + '.rst')
#         self.load()
# 
#     def add_comment(self, *args, **kw):
#         return self.thread.add_comment(*args, **kw)
# 
#     def asjson(self):
#         comments = [comment.asjson() for comment in
#                     self.thread.get_comments()]
# 
#         return {'article_uuid': self.article_uuid,
#                 'thread_uuid': self.thread_uuid,
#                 'comments': comments}
# 
#     def save(self):
#         with open(self.filename, 'w') as f:
#             f.write(self.render().encode('utf8'))
#         self.thread.save()
# 
#     def load(self):
#         if not os.path.exists(self.filename):
#             self.thread = Thread(self.storage_dir, self.thread_uuid)
#             self.thread_uuid = self.thread.uuid
#         else:
#             with open(self.filename) as f:
#                 uuids = f.read().split(':')
#             self.article_uuid = uuids[0]
#             self.thread_uuid = uuids[1]
#             self.thread = Thread(self.storage_dir, self.thread_uuid)
# 
#         self.thread.link_to_article(self.article_uuid)
# 
#     def render(self):
#         return u'%s:%s' % (self.article_uuid, self.thread_uuid)
# 
#     @classmethod
#     def loadfromfile(cls, filename):
#         storage_dir = os.path.dirname(filename)
#         klass = ArticleThread(storage_dir)
#         klass.filename = filename
#         klass.load()
#         return klass
# 
# class CommentsDB(object):
#     def __init__(self, storage_dir):
#         self.storage_dir = storage_dir
#         if not os.path.exists(storage_dir):
#             os.makedirs(storage_dir)
# 
#     def _get_comment(self, uuid):
#         thread = comment = None
#         for file in os.listdir(self.storage_dir):
#             if not file.startswith('thread_'):
#                 continue
#             filename = os.path.join(self.storage_dir, file)
#             thread = Thread.loadfromfile(filename)
#             try:
#                 comment = thread.get_comment(uuid)
#                 break
#             except KeyError:
#                 pass
#         if comment is None:
#             thread = None
#         return thread, comment
# 
#     def activate_comment(self, uuid):
#         thread, comment = self._get_comment(uuid)
#         if thread is not None:
#             thread.activate_comment(comment.uuid)
#             thread.save()
# 
#     def reject_comment(self, uuid):
#         thread, comment = self._get_comment(uuid)
#         if thread is not None:
#             thread.reject_comment(comment.uuid)
#             thread.save()
# 
#     def _get_comments(self, inactive=True, active=False,
#                       article_uuid=None):
#         for file in os.listdir(self.storage_dir):
#             if not file.startswith('article_'):
#                 continue
#             filename = os.path.join(self.storage_dir, file)
#             article_thread = ArticleThread.loadfromfile(filename)
#             thread = article_thread.thread
# 
#             if (article_uuid is not None and
#                     article_thread.article_uuid != article_uuid):
#                 continue
# 
#             for comment in thread.get_comments(include_inactive=inactive,
#                                                include_active=active):
#                 yield comment
# 
#     def get_moderation_queue(self):
#         return self._get_comments()
# 
#     def get_comments(self, article_uuid=None):
#         return self._get_comments(inactive=False, active=True,
#                                   article_uuid=article_uuid)
# 
# Path: henet/events.py
# def emit(event, **data):
#     for subscriber in _SUBSCRIBERS[event]:
#         subscriber(event, **data)
#     for subscriber in _SUBSCRIBERS[ALL_EVENTS]:
#         subscriber(event, **data)
# 
# EVENT_CREATED_COMMENT = 3
# 
# Path: henet/rst/rst2html.py
# def rst2html(rst, theme=None, opts=None, body_only=False):
#     rst_opts = default_rst_opts.copy()
#     rst_opts['warning_stream'] = StringIO()
# 
#     if body_only:
#         out = publish_parts(rst, writer_name='html',
#                             settings_overrides=rst_opts)['html_body']
# 
#         rst_opts['warning_stream'].seek(0)
#         warnings = rst_opts['warning_stream'].read()
#         return out, warnings
# 
#     if opts:
#         rst_opts.update(opts)
#     rst_opts['template'] = os.path.join(THEMES, 'template.txt')
# 
#     stylesheets = ['basic.css']
#     if theme:
#         stylesheets.append('%s/%s.css' % (theme, theme))
#     rst_opts['stylesheet'] = ','.join([J(THEMES, p) for p in stylesheets])
# 
#     out = publish_string(rst, writer_name='html', settings_overrides=rst_opts)
# 
#     rst_opts['warning_stream'].seek(0)
#     warnings = rst_opts['warning_stream'].read()
#     return out, warnings


# Path: henet/views/comments.py
import datetime
from bottle import route, request, app, response, get, post, redirect
from bottle_utils.csrf import csrf_protect, csrf_token
from henet.comments import ArticleThread, CommentsDB
from henet.events import emit, EVENT_CREATED_COMMENT
from henet.rst.rst2html import rst2html

# encoding: utf8



def enable_cors(func):
    def _enable_cors(*args, **kwargs):
        hds = response.headers
        hds['Access-Control-Allow-Origin'] = '*'

        hds['Access-Control-Allow-Methods'] = ', '.join(['PUT', 'GET',