# -*- coding:UTF-8  -*-
"""
篠田麻里子博客图片爬虫
http://blog.mariko-shinoda.net/
@author: hikaru
email: hikaru870806@hotmail.com
如有问题或建议请联系
"""
import os
import re
import traceback
from common import *


# 获取指定页数的全部日志
def get_one_page_blog(page_count):
    blog_pagination_url = "http://blog.mariko-shinoda.net/page%s.html" % (page_count - 1)
    result = {
        "blog_info_list": [],  # 全部日志信息
        "is_over": False,  # 是否最后一页日志
    }
    blog_pagination_response = net.http_request(blog_pagination_url, method="GET")
    if blog_pagination_response.status != net.HTTP_RETURN_CODE_SUCCEED:
        raise crawler.CrawlerException(crawler.request_failre(blog_pagination_response.status))
    blog_pagination_response_content = blog_pagination_response.data.decode(errors="ignore")
    # 检测是不是最后一页
    result["is_over"] = blog_pagination_response_content == "記事が存在しません。"
    if result["is_over"]:
        return result
    # 获取图片名字
    blog_html_find = re.findall("<section>([\s|\S]*?)</section>", blog_pagination_response_content)
    if len(blog_html_find) == 0:
        raise crawler.CrawlerException("页面匹配日志信息失败\n%s" % blog_pagination_response_content)
    for blog_html in blog_html_find:
        result_blog_info = {
            "blog_id": None,  # 日志id
            "photo_url_list": [],  # 图片地址列表
        }
        photo_name_list = re.findall('data-original="./([^"]*)"', blog_html)
        if len(photo_name_list) == 0:
            continue
        blog_id = photo_name_list[0].split("-")[0]
        if not crawler.is_integer(blog_id):
            raise crawler.CrawlerException("图片名字截取日志id失败\n%s" % blog_html)
        result_blog_info["blog_id"] = int(blog_id)
        for photo_name in photo_name_list:
            result_blog_info["photo_url_list"].append("http://blog.mariko-shinoda.net/%s" % photo_name)
        result["blog_info_list"].append(result_blog_info)
    return result


class Blog(crawler.Crawler):
    def __init__(self, **kwargs):
        # 设置APP目录
        crawler.PROJECT_APP_PATH = os.path.abspath(os.path.dirname(__file__))

        # 初始化参数
        sys_config = {
            crawler.SYS_DOWNLOAD_PHOTO: True,
            crawler.SYS_NOT_CHECK_SAVE_DATA: True,
        }
        crawler.Crawler.__init__(self, sys_config, **kwargs)

    def main(self):
        # 解析存档文件
        # photo_count  last_blog_id
        save_info = ["0", "0"]
        if os.path.exists(self.save_data_path):
            file_save_info = file.read_file(self.save_data_path).split("\t")
            if len(file_save_info) >= 2 and crawler.is_integer(file_save_info[0]) and crawler.is_integer(file_save_info[1]):
                save_info = file_save_info
            else:
                log.error("存档内数据格式不正确")
                tool.process_exit()
        temp_path_list = []

        try:
            page_count = 1
            blog_info_list = []
            is_over = False
            # 获取全部还未下载过需要解析的日志
            while not is_over:
                if not self.is_running():
                    tool.process_exit(0)
                log.step("开始解析第%s页日志" % page_count)

                # 获取一页日志
                try:
                    blog_pagination_response = get_one_page_blog(page_count)
                except crawler.CrawlerException as e:
                    log.error("第%s页日志解析失败，原因：%s" % (page_count, e.message))
                    raise

                # 是否已经获取完毕
                if blog_pagination_response["is_over"]:
                    break

                # 获取页面内的全部图片
                log.trace("第%s页解析的全部日志：%s" % (page_count, blog_pagination_response["blog_info_list"]))
                log.step("第%s页解析获取%s个日志" % (page_count, len(blog_pagination_response["blog_info_list"])))

                # 寻找这一页符合条件的日志
                for blog_info in blog_pagination_response["blog_info_list"]:
                    # 检查是否达到存档记录
                    if blog_info["blog_id"] > int(save_info[1]):
                        blog_info_list.append(blog_info)
                    else:
                        is_over = True
                        break

                if not is_over:
                    page_count += 1

            log.step("需要下载的全部日志解析完毕，共%s个" % len(blog_info_list))

            # 从最早的日志开始下载
            while len(blog_info_list) > 0:
                blog_info = blog_info_list.pop()
                log.step("开始解析日志 %s" % blog_info["blog_id"])

                photo_index = int(save_info[0]) + 1
                for photo_url in blog_info["photo_url_list"]:
                    if not self.is_running():
                        tool.process_exit(0)
                    log.step("开始下载第%s张图片 %s" % (photo_index, photo_url))

                    file_path = os.path.join(self.photo_download_path, "%05d.%s" % (photo_index, net.get_file_type(photo_url)))
                    save_file_return = net.save_net_file(photo_url, file_path)
                    if save_file_return["status"] == 1:
                        temp_path_list.append(file_path)
                        log.step("第%s张图片下载成功" % photo_index)
                        photo_index += 1
                    else:
                        log.step("第%s张图片 %s 下载失败，原因：%s" % (photo_index, photo_url, crawler.download_failre(save_file_return["code"])))

                # 日志内图片全部下载完毕
                temp_path_list = []  # 临时目录设置清除
                self.total_photo_count += (photo_index - 1) - int(save_info[0])  # 计数累加
                save_info[0] = str(photo_index - 1)  # 设置存档记录
                save_info[1] = str(blog_info["blog_id"])  # 设置存档记录
        except SystemExit as se:
            if se.code == 0:
                log.step("提前退出")
            else:
                log.error("异常退出")
            # 如果临时目录变量不为空，表示某个图集正在下载中，需要把下载了部分的内容给清理掉
            if len(temp_path_list) > 0:
                for temp_path in temp_path_list:
                    path.delete_dir_or_file(temp_path)
        except Exception as e:
            log.error("未知异常")
            log.error(str(e) + "\n" + traceback.format_exc())

        # 保存新的存档文件
        file.write_file("\t".join(save_info), self.save_data_path, file.WRITE_FILE_TYPE_REPLACE)
        log.step("全部下载完毕，耗时%s秒，共计图片%s张" % (self.get_run_time(), self.total_photo_count))


if __name__ == "__main__":
    Blog().main()
