# Path: maple/assertion.py
# def assert_request(assertion, include=[], exclude=[]):
#     def _assert_request(func):
#         @wraps(func)
#         def decorator(*args, **kwargs):
#             data = request.data
#             resp = assertion(data, include, exclude)()
#             if resp is not None:
#                 return resp
#             return func(*args, **kwargs)
# 
#         return decorator
# 
#     return _assert_request
# 
# Path: maple/blog/assertion.py
# class ArticleAssert(Assert):
#     def assert_title(self, value):
#         self.assertRequire(value, "title is required")
# 
#     def assert_content(self, value):
#         self.assertRequire(value, "content is required")
# 
#     def assert_content_type(self, value):
#         self.assertIn(value, ["0", "1"])
# 
#     def assert_category(self, value):
#         pass
# 
#     def assert_tags(self, value):
#         pass
# 
# Path: maple/blog/db.py
# class Article(db.Model, ModelUserMixin):
#     __tablename__ = 'article'
# 
#     CONTENT_TYPE_MARKDOWN = 0
#     CONTENT_TYPE_ORGMODE = 1
# 
#     CONTENT_TYPE = ((0, 'markdown'), (1, 'org-mode'))
# 
#     id = db.Column(db.Integer, primary_key=True)
#     title = db.Column(db.String(50), nullable=False)
#     content = db.Column(db.Text, nullable=False)
#     content_type = db.Column(
#         db.Integer, nullable=False, default=CONTENT_TYPE_MARKDOWN)
# 
#     category_id = db.Column(
#         db.Integer,
#         db.ForeignKey('category.id', ondelete="CASCADE"),
#         nullable=False)
#     category = db.relationship(
#         'Category',
#         backref=db.backref(
#             'articles', cascade='all,delete-orphan', lazy='dynamic'),
#         uselist=False,
#         lazy='joined')
# 
#     __mapper_args__ = {"order_by": text("created_at desc")}
# 
#     def __repr__(self):
#         return "<Article %r>" % self.title
# 
#     def __str__(self):
#         return self.title
# 
#     def to_json(self):
#         return {
#             'id': self.id,
#             'title': self.title,
#             'category': self.category.name,
#             'tags': ','.join([tag.name for tag in self.tags]),
#         }
# 
#     def to_html(self, length=None, truncate=False):
#         length = length or current_app.config.get("SUMMARY_MAX_LENGTH")
#         if not truncate:
#             length = None
#         if self.content_type == self.CONTENT_TYPE_MARKDOWN:
#             return markdown_to_html(self.content, length)
#         return orgmode_to_html(self.content, length)
# 
#     @property
#     def htmlcontent(self):
#         return self.to_html()
# 
#     @property
#     def next_article(self):
#         return Article.query.filter_by(id__lt=self.id).order_by("-id").first()
# 
#     @property
#     def previous_article(self):
#         return Article.query.filter_by(id__gt=self.id).order_by("id").first()
# 
#     @property
#     def read_times(self):
#         return Count.get('article:{}'.format(self.id))
# 
#     @read_times.setter
#     def read_times(self, value):
#         Count.set('article:{}'.format(self.id))
# 
# Path: maple/blog/serializer.py
# class ArticleSerializer(Serializer):
#     class Meta:
#         exclude = ["user", "user_id"]
#         extra = ["htmlcontent"]
# 
# Path: maple/utils.py
# def filter_maybe(request_data, columns, params=None):
#     if params is None:
#         params = dict()
#     is_dict = isinstance(columns, dict)
#     for column in columns:
#         value = request_data.get(column)
#         if not value:
#             continue
#         key = column if not is_dict else columns.get(column, column)
# 
#         if key in ["created_at__gte", "created_at__lte"]:
#             value = datetime.strptime(value, '%Y-%m-%d')
#         params.update({key: value})
#     return params
# 
# class AuthMethodView(MethodView):
#     decorators = (login_required, )


from flask import request
from flask_maple.response import HTTP
from maple.assertion import assert_request
from maple.blog.assertion import ArticleAssert
from maple.blog.db import Article
from maple.blog.serializer import ArticleSerializer
from maple.utils import filter_maybe, AuthMethodView
# Copyright © 2019 jianglin
# File Name: article.py
# Author: jianglin
# Email: mail@honmaple.com
# Created: 2019-07-12 10:18:31 (CST)
# Last Update: Monday 2019-09-23 17:06:31 (CST)
#          By:
# Description:
# ********************************************************************************


class ArticleAPI(AuthMethodView):
    def get(self):
        data = request.data
        page, number = self.pageinfo
        params = filter_maybe(
            data, {
                "tag": "tags__name",
                "category": "category__name",
                "title": "title__contains",
                "year": "created_at__year",
                "month": "created_at__month"
            })
        order_by = ("-created_at", )

        ins = Article.query.filter_by(**params).order_by(*order_by).paginate(
            page, number)
        serializer = ArticleSerializer(ins)
        return HTTP.OK(data=serializer.data)


# Path: maple/assertion.py
# def assert_request(assertion, include=[], exclude=[]):
#     def _assert_request(func):
#         @wraps(func)
#         def decorator(*args, **kwargs):
#             data = request.data
#             resp = assertion(data, include, exclude)()
#             if resp is not None:
#                 return resp
#             return func(*args, **kwargs)
# 
#         return decorator
# 
#     return _assert_request
# 
# Path: maple/blog/assertion.py
# class ArticleAssert(Assert):
#     def assert_title(self, value):
#         self.assertRequire(value, "title is required")
# 
#     def assert_content(self, value):
#         self.assertRequire(value, "content is required")
# 
#     def assert_content_type(self, value):
#         self.assertIn(value, ["0", "1"])
# 
#     def assert_category(self, value):
#         pass
# 
#     def assert_tags(self, value):
#         pass
# 
# Path: maple/blog/db.py
# class Article(db.Model, ModelUserMixin):
#     __tablename__ = 'article'
# 
#     CONTENT_TYPE_MARKDOWN = 0
#     CONTENT_TYPE_ORGMODE = 1
# 
#     CONTENT_TYPE = ((0, 'markdown'), (1, 'org-mode'))
# 
#     id = db.Column(db.Integer, primary_key=True)
#     title = db.Column(db.String(50), nullable=False)
#     content = db.Column(db.Text, nullable=False)
#     content_type = db.Column(
#         db.Integer, nullable=False, default=CONTENT_TYPE_MARKDOWN)
# 
#     category_id = db.Column(
#         db.Integer,
#         db.ForeignKey('category.id', ondelete="CASCADE"),
#         nullable=False)
#     category = db.relationship(
#         'Category',
#         backref=db.backref(
#             'articles', cascade='all,delete-orphan', lazy='dynamic'),
#         uselist=False,
#         lazy='joined')
# 
#     __mapper_args__ = {"order_by": text("created_at desc")}
# 
#     def __repr__(self):
#         return "<Article %r>" % self.title
# 
#     def __str__(self):
#         return self.title
# 
#     def to_json(self):
#         return {
#             'id': self.id,
#             'title': self.title,
#             'category': self.category.name,
#             'tags': ','.join([tag.name for tag in self.tags]),
#         }
# 
#     def to_html(self, length=None, truncate=False):
#         length = length or current_app.config.get("SUMMARY_MAX_LENGTH")
#         if not truncate:
#             length = None
#         if self.content_type == self.CONTENT_TYPE_MARKDOWN:
#             return markdown_to_html(self.content, length)
#         return orgmode_to_html(self.content, length)
# 
#     @property
#     def htmlcontent(self):
#         return self.to_html()
# 
#     @property
#     def next_article(self):
#         return Article.query.filter_by(id__lt=self.id).order_by("-id").first()
# 
#     @property
#     def previous_article(self):
#         return Article.query.filter_by(id__gt=self.id).order_by("id").first()
# 
#     @property
#     def read_times(self):
#         return Count.get('article:{}'.format(self.id))
# 
#     @read_times.setter
#     def read_times(self, value):
#         Count.set('article:{}'.format(self.id))
# 
# Path: maple/blog/serializer.py
# class ArticleSerializer(Serializer):
#     class Meta:
#         exclude = ["user", "user_id"]
#         extra = ["htmlcontent"]
# 
# Path: maple/utils.py
# def filter_maybe(request_data, columns, params=None):
#     if params is None:
#         params = dict()
#     is_dict = isinstance(columns, dict)
#     for column in columns:
#         value = request_data.get(column)
#         if not value:
#             continue
#         key = column if not is_dict else columns.get(column, column)
# 
#         if key in ["created_at__gte", "created_at__lte"]:
#             value = datetime.strptime(value, '%Y-%m-%d')
#         params.update({key: value})
#     return params
# 
# class AuthMethodView(MethodView):
#     decorators = (login_required, )


# Path: maple/blog/api/article.py
from flask import request
from flask_maple.response import HTTP
from maple.assertion import assert_request
from maple.blog.assertion import ArticleAssert
from maple.blog.db import Article
from maple.blog.serializer import ArticleSerializer
from maple.utils import filter_maybe, AuthMethodView

# Copyright © 2019 jianglin
# File Name: article.py
# Author: jianglin
# Email: mail@honmaple.com
# Created: 2019-07-12 10:18:31 (CST)
# Last Update: Monday 2019-09-23 17:06:31 (CST)
#          By:
# Description:
# ********************************************************************************


class ArticleAPI(AuthMethodView):
    def get(self):
        data = request.data
        page, number = self.pageinfo
        params = filter_maybe(
            data, {
                "tag": "tags__name",
                "category": "category__name",
                "title": "title__contains",
                "year": "created_at__year",
                "month": "created_at__month"
            })
        order_by = ("-created_at", )

        ins = Article.query.filter_by(**params).order_by(*order_by).paginate(
            page, number)
        serializer = ArticleSerializer(ins)
        return HTTP.OK(data=serializer.data)


    @assert_request(ArticleAssert)