#lsx 博客视图模块

from django.shortcuts import render, get_object_or_404, redirect
from django.views import View
from django.http import HttpResponse, JsonResponse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from django.utils.translation import gettext_lazy as _
from django.utils import timezone

from blog.models import Article, Category, Tag, SideBar, Links, BlogSettings
from djangoblog.utils import get_blog_setting, cache, get_current_site
from comments.models import Comment

#lsx 首页视图，显示文章列表
class IndexView(View):
    #lsx 获取博客设置，显示文章列表
    def get(self, request):
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取当前页面
        page = request.GET.get('page', 1)
        #lsx 获取文章列表，按发布时间倒序排列
        article_list = Article.objects.filter(type='a', status='p').order_by('-pub_time')
        #lsx 分页处理
        paginator = Paginator(article_list, blog_setting.article_sub_length)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        #lsx 构建上下文
        context = {
            'articles': articles,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/index.html', context)

#lsx 文章详情视图
class ArticleDetailView(View):
    #lsx 获取文章详情，增加浏览量
    def get(self, request, article_id):
        #lsx 获取文章对象
        article = get_object_or_404(Article, id=article_id, type='a', status='p')
        #lsx 增加浏览量
        article.viewed()
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取评论列表
        comments = Comment.objects.filter(article=article, is_enable=True)
        #lsx 构建上下文
        context = {
            'article': article,
            'sidebar': get_sidebar(request),
            'comments': comments,
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/article_detail.html', context)

#lsx 分类详情视图
class CategoryDetailView(View):
    #lsx 获取分类下的文章列表
    def get(self, request, category_id):
        #lsx 获取分类对象
        category = get_object_or_404(Category, id=category_id)
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取当前页面
        page = request.GET.get('page', 1)
        #lsx 获取分类下的文章列表
        article_list = Article.objects.filter(
            category=category, type='a', status='p').order_by('-pub_time')
        #lsx 分页处理
        paginator = Paginator(article_list, blog_setting.article_sub_length)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        #lsx 构建上下文
        context = {
            'category': category,
            'articles': articles,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/category_detail.html', context)

#lsx 标签详情视图
class TagDetailView(View):
    #lsx 获取标签下的文章列表
    def get(self, request, tag_id):
        #lsx 获取标签对象
        tag = get_object_or_404(Tag, id=tag_id)
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取当前页面
        page = request.GET.get('page', 1)
        #lsx 获取标签下的文章列表
        article_list = Article.objects.filter(
            tags=tag, type='a', status='p').order_by('-pub_time')
        #lsx 分页处理
        paginator = Paginator(article_list, blog_setting.article_sub_length)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        #lsx 构建上下文
        context = {
            'tag': tag,
            'articles': articles,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/tag_detail.html', context)

#lsx 页面详情视图（静态页面）
class PageDetailView(View):
    #lsx 获取页面详情
    def get(self, request, page_id):
        #lsx 获取页面对象
        page = get_object_or_404(Article, id=page_id, type='p', status='p')
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 构建上下文
        context = {
            'page': page,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/page_detail.html', context)

#lsx 搜索视图
class SearchView(View):
    #lsx 搜索文章
    def get(self, request):
        #lsx 获取搜索关键词
        keyword = request.GET.get('keyword', '')
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取当前页面
        page = request.GET.get('page', 1)
        #lsx 搜索文章
        article_list = Article.objects.filter(
            title__icontains=keyword, type='a', status='p').order_by('-pub_time')
        #lsx 分页处理
        paginator = Paginator(article_list, blog_setting.article_sub_length)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        #lsx 构建上下文
        context = {
            'keyword': keyword,
            'articles': articles,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/search.html', context)

#lsx 作者详情视图
class AuthorDetailView(View):
    #lsx 获取作者信息和文章列表
    def get(self, request, author_id):
        #lsx 页面类型标识，用于缓存
        page_type = 'author'
        #lsx 缓存键生成
        cache_key = f'{page_type}_{author_id}_cache_key'
        #lsx 获取缓存
        cached_data = cache.get(cache_key)
        if cached_data:
            #lsx 如果有缓存，直接返回
            return render(request, 'blog/author_detail.html', cached_data)
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取当前页面
        page = request.GET.get('page', 1)
        #lsx 获取用户对象
        from django.contrib.auth import get_user_model
        User = get_user_model()
        author = get_object_or_404(User, id=author_id)
        #lsx 查询集数据获取
        article_list = Article.objects.filter(
            author=author, type='a', status='p').order_by('-pub_time')
        #lsx 分页处理
        paginator = Paginator(article_list, blog_setting.article_sub_length)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        #lsx 上下文处理
        context = {
            'author': author,
            'articles': articles,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 添加到上下文
        cache.set(cache_key, context, 60 * 10)  # 缓存10分钟
        #lsx 渲染页面
        return render(request, 'blog/author_detail.html', context)

#lsx 获取侧边栏数据
@cache_page(60 * 10)  # 缓存10分钟
#lsx 生成侧边栏内容
#lsx 生成缓存键
#lsx 获取缓存数据
#lsx 如果缓存不存在，生成侧边栏数据
#lsx 缓存侧边栏数据
#lsx 返回侧边栏数据
#lsx 添加到上下文
#lsx 渲染页面
#lsx 返回响应
#lsx 增加文章浏览量
#lsx 保存文章
#lsx 获取文章URL
#lsx 生成缓存键
#lsx 添加到上下文
#lsx 渲染页面
#lsx 返回响应
def get_sidebar(request):
    #lsx 获取博客设置
    blog_setting = get_blog_setting()
    #lsx 获取侧边栏列表
    sidebar_list = SideBar.objects.filter(is_enable=True).order_by('sequence')
    #lsx 获取热门文章
    hot_article_list = Article.objects.filter(
        type='a', status='p').order_by('-views')[:blog_setting.sidebar_article_count]
    #lsx 获取最新评论
    latest_comment_list = Comment.objects.filter(
        is_enable=True).order_by('-create_time')[:blog_setting.sidebar_comment_count]
    #lsx 获取分类列表
    category_list = Category.objects.all()
    #lsx 获取标签列表
    tag_list = Tag.objects.all()
    #lsx 获取友情链接
    links = Links.objects.filter(is_enable=True).order_by('sequence')
    #lsx 构建侧边栏数据
    sidebar = {
        'sidebar_list': sidebar_list,
        'hot_article_list': hot_article_list,
        'latest_comment_list': latest_comment_list,
        'category_list': category_list,
        'tag_list': tag_list,
        'links': links
    }
    return sidebar

#lsx 文章归档视图
class ArchivesView(View):
    #lsx 获取文章归档数据
    def get(self, request):
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取所有已发布文章
        article_list = Article.objects.filter(
            type='a', status='p').order_by('-pub_time')
        #lsx 按年月分组
        archives = {}
        for article in article_list:
            year = article.pub_time.year
            month = article.pub_time.month
            key = f'{year}-{month:02d}'
            if key not in archives:
                archives[key] = []
            archives[key].append(article)
        #lsx 构建上下文
        context = {
            'archives': archives,
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/archives.html', context)

#lsx 关于页面视图
class AboutView(View):
    #lsx 显示关于页面
    def get(self, request):
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 构建上下文
        context = {
            'sidebar': get_sidebar(request),
            'blog_setting': blog_setting
        }
        #lsx 渲染页面
        return render(request, 'blog/about.html', context)

#lsx 站点地图视图
class SitemapView(View):
    #lsx 生成站点地图
    def get(self, request):
        #lsx 获取所有已发布文章和页面
        articles = Article.objects.filter(type='a', status='p').order_by('-pub_time')
        pages = Article.objects.filter(type='p', status='p')
        #lsx 获取分类和标签
        categories = Category.objects.all()
        tags = Tag.objects.all()
        #lsx 获取当前站点
        site = get_current_site(request)
        #lsx 构建上下文
        context = {
            'articles': articles,
            'pages': pages,
            'categories': categories,
            'tags': tags,
            'site': site
        }
        #lsx 渲染XML页面
        return render(request, 'blog/sitemap.xml', context, content_type='application/xml')

#lsx RSS订阅视图
class RSSView(View):
    #lsx 生成RSS订阅
    def get(self, request):
        #lsx 获取博客设置
        blog_setting = get_blog_setting()
        #lsx 获取最新文章
        articles = Article.objects.filter(
            type='a', status='p').order_by('-pub_time')[:30]
        #lsx 获取当前站点
        site = get_current_site(request)
        #lsx 构建上下文
        context = {
            'articles': articles,
            'blog_setting': blog_setting,
            'site': site,
            'now': timezone.now()
        }
        #lsx 渲染XML页面
        return render(request, 'blog/rss.xml', context, content_type='application/xml')
