import json
import os
import re
import sys
import time
import urllib.parse
from collections import OrderedDict
from datetime import datetime
from pathlib import Path
from xml.sax.saxutils import escape

import xmltodict
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QLabel, QRadioButton, QVBoxLayout, QHBoxLayout, QWidget, \
    QButtonGroup, QProgressBar, QCheckBox, QPushButton, QLineEdit, QTextEdit, QDesktopWidget, QMainWindow, \
    QAction, qApp, QApplication, QGridLayout, QMessageBox
from markdownify import markdownify as md
from pathvalidate import sanitize_filename

p_server = re.compile(r'(imglf\d?)', re.I)

p_img = re.compile(r'<img src="([^"]+?)"([^>]*)>', re.I)

p_ext_img = re.compile(r'<img src="([^"]+?)"[^>]*>', re.I)

gh_prefix = 'raw.githubusercontent.com'

# LOFTER-墨问非名-2019.03.29.xml
p_lofter = re.compile(r'^LOFTER-(.*)-(\d{4}\.\d{2}\.\d{2})')

header = '''<?xml version="1.0" encoding="UTF-8" ?>
<!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
<!-- It contains information about your site's posts, pages, comments, categories, and other content. -->
<!-- You may use this file to transfer that content from one site to another. -->
<!-- This file is not intended to serve as a complete backup of your site. -->

<!-- To import this information into a WordPress site follow these steps: -->
<!-- 1. Log in to that site as an administrator. -->
<!-- 2. Go to Tools: Import in the WordPress admin panel. -->
<!-- 3. Install the "WordPress" importer from the list. -->
<!-- 4. Activate & Run Importer. -->
<!-- 5. Upload this file using the form provided on that page. -->
<!-- 6. You will first be asked to map the authors in this export file to users -->
<!--    on the site. For each author, you may choose to map to an -->
<!--    existing user on the site or to create a new user. -->
<!-- 7. WordPress will then import each of the posts, pages, comments, categories, etc. -->
<!--    contained in this file into your site. -->

<!-- generator="WordPress.com" created="2019-06-08 20:37"-->
<rss version="2.0"
	xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:wp="http://wordpress.org/export/1.2/"
>
'''

channel_header = '''<channel>
<title>lolirabbit</title>
<link>https://lolirabbit.wordpress.com</link>
<description></description>
<pubDate>Sat, 08 Jun 2019 20:37:37 +0000</pubDate>
<language></language>
<wp:wxr_version>1.2</wp:wxr_version>
<wp:base_site_url>http://wordpress.com/</wp:base_site_url>
<wp:base_blog_url>https://lolirabbit.wordpress.com</wp:base_blog_url>
<wp:author>
<wp:author_id>82339102</wp:author_id>
<wp:author_login>
<![CDATA[anywaywillgo]]>
</wp:author_login>
<wp:author_email>
<![CDATA[anywaywillgo@gmail.com]]>
</wp:author_email>
<wp:author_display_name>
<![CDATA[anywaywillgo]]>
</wp:author_display_name>
<wp:author_first_name>
<![CDATA[]]>
</wp:author_first_name>
<wp:author_last_name>
<![CDATA[]]>
</wp:author_last_name>
</wp:author>
<generator>http://wordpress.com/</generator>
<image>
    <url>http://s0.wp.com/i/buttonw-com.png</url>
    <title>lolirabbit</title>
    <link>https://lolirabbit.wordpress.com</link>
</image>
'''

footer = '''</channel>
</rss>'''

sample_item_a = '''
<wp:comment_status>open</wp:comment_status>
<wp:ping_status>open</wp:ping_status>'''

sample_item_b = '''
<wp:status>publish</wp:status>
<wp:post_parent>0</wp:post_parent>
<wp:menu_order>0</wp:menu_order>
<wp:post_type>post</wp:post_type>
<wp:post_password></wp:post_password>
<wp:is_sticky>0</wp:is_sticky>
'''

sample_item_footer = '''
<wp:postmeta>
    <wp:meta_key>timeline_notification</wp:meta_key>
    <wp:meta_value><![CDATA[1560026174]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
    <wp:meta_key>_rest_api_published</wp:meta_key>
    <wp:meta_value><![CDATA[1]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
    <wp:meta_key>_rest_api_client_id</wp:meta_key>
    <wp:meta_value><![CDATA[-1]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
    <wp:meta_key>_publicize_job_id</wp:meta_key>
    <wp:meta_value><![CDATA[31631303363]]></wp:meta_value>
</wp:postmeta>
</item>
'''
wordpress_prefix = 'https://samplewordpressblog.wordpress.com/'


def get_di_files_w_suffix(rootdir, suffixes):
    file_paths = []
    files = os.listdir(rootdir)
    if isinstance(suffixes, str):
        suffixes = (suffixes,)
    for file in files:
        file_path = Path(rootdir) / file
        if file_path.suffix.lower() in suffixes and file_path.is_file():
            file_paths.append(file_path)
    file_paths.sort()
    return file_paths


def get_di_xml(rootdir):
    suffixes = ".xml"
    return get_di_files_w_suffix(rootdir, suffixes)


# ================创建目录================
def make_dir(file_path):
    if not os.path.exists(file_path):
        try:
            os.mkdir(file_path)
        except:
            pass


# ================运行时间计时================
def run_time(start_time):
    '''
    :param start_time:
    :return: 运行时间
    '''
    run_time = time.time() - start_time
    if run_time < 60:  # 两位小数的秒
        show_run_time = '{:.2f}秒'.format(run_time)
    elif run_time < 3600:  # 分秒取整
        show_run_time = '{:.0f}分{:.0f}秒'.format(run_time // 60, run_time % 60)
    else:  # 时分秒取整
        show_run_time = '{:.0f}时{:.0f}分{:.0f}秒'.format(run_time // 3600, run_time % 3600 // 60, run_time % 60)
    return show_run_time


def list2str(some_list):
    some_string = ''
    if isinstance(some_list, list):
        some_string = "[" + ", ".join(some_list) + "]"
    elif isinstance(some_list, str):
        some_string = some_list
    return some_string


def format_hugo_title(title):
    if "'" in title or "#" in title or "@" in title or "[" in title or "]" in title or "+" in title or "!" in title or ":" in title or title.isdigit():  # or "：" in title or "（" in title or "）" in title
        title_info = '"' + title + '"'
    else:
        title_info = title
    return title_info


def safe(title):
    safe_title = title.replace(':', '：')
    safe_title = safe_title.replace('!', '！')
    safe_title = safe_title.replace("'", "-")
    # safe_title = title.replace("'", "’")
    safe_title = safe_title.replace('/', '／')
    safe_title = safe_title.replace('\\', '＼')
    safe_title = sanitize_filename(safe_title)
    return safe_title


# ================写入文件================
def write_text(file_path, text):
    f = open(file_path, mode='w', encoding="utf-8")
    try:
        f.write(text)
    finally:
        f.close()


def deduce_list(input_list):
    output_list = list(OrderedDict.fromkeys(input_list))
    return output_list


def int2time(timestamp, formatter='%Y-%m-%d %H:%M:%S'):
    timestamp = int(timestamp)
    timestamp = timestamp / 1000
    time_str = datetime.utcfromtimestamp(timestamp).strftime(formatter)

    return time_str


def get_head_matter(export_type, title, publishTime, modifyTime, author, categories, tags, permalink, description=''):
    # ================构造头部================
    content = '---'
    title_info = format_hugo_title(title)

    permalink_lower = permalink.lower()
    slug = '"' + permalink_lower + '"'

    if export_type == 'Hugo':
        publishTime = publishTime.replace(' ', 'T') + '+08:00'
        modifyTime = modifyTime.replace(' ', 'T') + '+08:00'

    content += '\ntitle: ' + title_info
    content += '\ndate: ' + publishTime
    content += '\ntags: ' + list2str(tags)

    if export_type == 'Hexo':
        content += '\ncategories: ' + list2str(categories)
        content += '\nupdated: ' + modifyTime
        content += '\npermalink: ' + permalink
        content += '\nauthor: "' + author + '"'
        content += '\ndescription: "' + description + '"'

    elif export_type == 'Hugo':
        content += '\ncategories: ' + list2str(categories)
        content += '\nlastmod: ' + modifyTime
        content += '\nslug: ' + permalink
        content += '\nauthor: "' + author + '"'
        content += '\ndescription: "' + description + '"'

    elif export_type == 'Jekyll':
        content += '\ncategories: ' + list2str(categories)

    elif export_type == 'Gridea':
        content += '\npublished: true'
        content += '\nhideInList: false'
        content += '\nfeature: '

    content += '\n---'
    return content


def get_comments(post, id2name_dict):
    md_comment_section = ''
    html_comment_section = ''

    commentList = post['commentList']
    comments = commentList['comment']
    if not isinstance(comments, list):
        comments = [comments]
    if comments:
        comments.reverse()

        md_comment_section += '\n\n<!-- more -->\n\n---\n'
        html_comment_section += '\n\n<p><!--more--></p>\n\n<hr />\n'

        for j in range(len(comments)):
            comment = comments[j]
            publisherUserId = comment['publisherUserId']
            publisherNick = comment['publisherNick']
            publisherContent = comment['content']
            commentPublishTime = comment['publishTime']
            commentPublishTime = int2time(commentPublishTime)
            replyToUserId = comment['replyToUserId']
            # decodedpublisherUserId = base64.b64decode(publisherUserId)  # 然而还是乱码……
            # decodedreplyToUserId = base64.b64decode(replyToUserId)  # 然而还是乱码……
            # publisherContentMD = html2text.html2text(publisherContent).strip('\r\n\t ')
            # publisherContentMD = md(publisherContent).strip('\r\n\t ')
            # publisherContentText = html.unescape(publisherContent)

            replyToStr = ''
            if replyToUserId in id2name_dict:
                Nicks = id2name_dict[replyToUserId]
                Nicks_only = [x[0] for x in Nicks]
                Nicks_only = deduce_list(Nicks_only)
                if len(Nicks_only) >= 2:
                    # print(Nicks)
                    pass
                Nicks.sort(key=lambda x: x[-1])
                Nick = Nicks[-1][0]
                replyToStr = ' 回复【' + md(Nick) + '】'

            md_line = '\n`' + commentPublishTime + '` 【' + md(publisherNick) + '】' + replyToStr + ' ' + md(
                publisherContent) + '\n'
            html_line = '\n<p><code>' + commentPublishTime + '</code> 【' + publisherNick + '】' + replyToStr + ' ' + publisherContent + '</p>\n'

            md_comment_section += md_line
            html_comment_section += html_line
    return md_comment_section, html_comment_section


def get_id2name_dict(doc):
    id2name_dict = {}
    posts = doc['lofterBlogExport']['PostItem']

    if not isinstance(posts, list):
        posts = [posts]

    posts.reverse()
    for i in range(len(posts)):
        post = posts[i]
        if 'commentList' in post:
            commentList = post['commentList']
            comments = commentList['comment']
            if not isinstance(comments, list):
                comments = [comments]
            for j in range(len(comments)):
                comment = comments[j]
                publisherUserId = comment['publisherUserId']
                publisherNick = comment['publisherNick']
                commentPublishTime = comment['publishTime']
                commentPublishTime = int2time(commentPublishTime)
                if publisherUserId not in id2name_dict:
                    id2name_dict[publisherUserId] = []
                tup = (publisherNick, commentPublishTime)
                id2name_dict[publisherUserId].append(tup)
    return id2name_dict


def get_item_str(i, title, publishTime, modifyTime, author, categories, tags, permalink, html_content):
    item_str = '<item>'
    link = wordpress_prefix + permalink
    pubDate = ''
    description = ''
    excerpt = ''
    post_id = 2 * i + 1
    post_date = publishTime
    post_date_gmt = publishTime
    item_str += '\n<title>' + escape(title) + '</title>'
    item_str += '\n<link>' + link + '</link>'
    item_str += '\n<pubDate>' + pubDate + '</pubDate>'
    item_str += '\n<dc:creator>' + author + '</dc:creator>'
    item_str += '\n<guid isPermaLink="false">https://lolirabbit.wordpress.com/?p=' + str(post_id) + '</guid>'
    item_str += '\n<description>' + description + '</description>'
    item_str += '\n<content:encoded><![CDATA[' + html_content + ']]></content:encoded>'
    item_str += '\n<excerpt:encoded><![CDATA[' + excerpt + ']]></excerpt:encoded>'
    item_str += '\n<wp:post_id>' + str(post_id) + '</wp:post_id>'
    item_str += '\n<wp:post_date>' + post_date + '</wp:post_date>'
    item_str += '\n<wp:post_date_gmt>' + post_date_gmt + '</wp:post_date_gmt>'
    item_str += sample_item_a
    item_str += '\n<wp:post_name>' + permalink + '</wp:post_name>'
    item_str += sample_item_b

    for category in categories:
        quote_category = urllib.parse.quote(category)
        example_category_str = '<category domain="category" nicename="' + quote_category + '"><![CDATA[' + category + ']]></category>'
        item_str += example_category_str

    for tag in tags:
        quote_tag = urllib.parse.quote(tag)
        example_tag_str = '<category domain="post_tag" nicename="' + quote_tag + '"><![CDATA[' + tag + ']]></category>'
        item_str += example_tag_str

    item_str += sample_item_footer
    return item_str


class MyWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # ================变量================
        # self.export_type = 'Hexo'
        # self.display_comments = True  # 是否在博文中显示历史评论

        # self.GitHubPathStr = '你的GitHub主文件夹路径'
        # self.owner = '你的GitHub账号名'
        # self.repo_name = '你存放图片的GitHub库名称'

        # ================组件================
        self.button = QPushButton('执行任务')
        self.button.setToolTip('点击此按钮')
        self.button.clicked.connect(self.onStartButton)

        self.label = QLabel('迁移到')
        self.rbtn1 = QRadioButton('Hexo')
        self.rbtn2 = QRadioButton('Hugo')
        self.rbtn3 = QRadioButton('Jekyll')
        self.rbtn4 = QRadioButton('Gridea')
        self.rbtn5 = QRadioButton('Wordpress')
        self.rbtn5.setChecked(True)

        self.cb1 = QCheckBox('在输出文件中包含评论', self)
        self.cb1.setChecked(True)
        # self.cb.stateChanged.connect(self.show_comments)
        self.cb2 = QCheckBox('强制转换图片网址到GitHub图床', self)

        self.label1 = QLabel('GitHub主文件夹')
        self.label2 = QLabel('GitHub账号名')
        self.label3 = QLabel('GitHub库名称')
        self.label4 = QLabel('当前文件夹')
        self.label5 = QLabel('读取自')
        self.label6 = QLabel('保存到文件夹')
        self.label7 = QLabel('调试信息')
        self.label8 = QLabel('调试日志')
        self.label9 = QLabel('进度')

        self.qle1 = QLineEdit(self)
        self.qle2 = QLineEdit(self)
        self.qle3 = QLineEdit(self)
        self.qle4 = QLineEdit(self)
        self.qle5 = QLineEdit(self)
        self.qle6 = QLineEdit(self)
        self.qle7 = QLineEdit(self)
        self.textEdit = QTextEdit()

        # self.qle7.setStyleSheet("QCustomLineEdit{color: gray;}")

        # self.qle4.setEnabled(False)
        # self.qle5.setEnabled(False)
        # self.qle6.setEnabled(False)
        # self.qle7.setEnabled(False)
        # self.textEdit.setEnabled(False)

        self.qle4.setReadOnly(True)
        self.qle5.setReadOnly(True)
        self.qle6.setReadOnly(True)
        self.qle7.setReadOnly(True)
        self.textEdit.setReadOnly(True)

        self.qle1.setPlaceholderText("你的GitHub主文件夹路径")
        self.qle2.setPlaceholderText("你的GitHub账号名")
        self.qle3.setPlaceholderText("你存放图片的GitHub库名称")
        self.qle4.setText(dirpath)

        self.pbar = QProgressBar(self)

        # ================状态栏================
        self.statusBar().showMessage('准备就绪')

        # ================菜单栏================
        helloAction = QAction('你好', self)
        helloAction.setShortcut('Ctrl+H')
        helloAction.setStatusTip('程序问候')
        helloAction.triggered.connect(self.onHello)

        # exitAction = QAction(QIcon('exit.png'), '&Exit', self)
        exitAction = QAction('退出', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('退出程序')
        exitAction.triggered.connect(qApp.quit)

        aboutAction = QAction('关于', self)
        aboutAction.setShortcut('Ctrl+A')
        aboutAction.setStatusTip('关于程序')
        aboutAction.triggered.connect(self.onAbout)

        # 创建一个菜单栏
        menubar = self.menuBar()
        # 添加菜单
        fileMenu = menubar.addMenu('文件')
        otherMenu = menubar.addMenu('其他')

        # 添加事件
        fileMenu.addAction(helloAction)
        fileMenu.addAction(exitAction)
        otherMenu.addAction(aboutAction)

        # ================工具栏================
        self.toolbar = self.addToolBar('工具')
        self.toolbar.addAction(exitAction)
        self.toolbar.addAction(helloAction)
        self.toolbar.addAction(aboutAction)

        # ================多选框组================
        self.btngroup = QButtonGroup()
        self.btngroup.setExclusive(True)
        self.btngroup.addButton(self.rbtn1)
        self.btngroup.addButton(self.rbtn2)
        self.btngroup.addButton(self.rbtn3)
        self.btngroup.addButton(self.rbtn4)
        self.btngroup.addButton(self.rbtn5)
        self.btngroup.buttonClicked.connect(self.on_click)

        # ================绑定================

        # ================布局================
        rbtnlayout = QHBoxLayout()
        rbtnlayout.addWidget(self.label)

        rbtnlayout.addWidget(self.rbtn1)
        rbtnlayout.addWidget(self.rbtn2)
        rbtnlayout.addWidget(self.rbtn3)
        rbtnlayout.addWidget(self.rbtn4)
        rbtnlayout.addWidget(self.rbtn5)
        rbtnlayout.addStretch(1)

        buttonlayout = QHBoxLayout()
        # buttonlayout.addStretch(1)
        buttonlayout.addWidget(self.button)
        buttonlayout.addStretch(1)

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(self.label1, 1, 0)
        grid.addWidget(self.qle1, 1, 1)
        grid.addWidget(self.label2, 2, 0)
        grid.addWidget(self.qle2, 2, 1)
        grid.addWidget(self.label3, 3, 0)
        grid.addWidget(self.qle3, 3, 1)
        grid.addWidget(self.label4, 4, 0)
        grid.addWidget(self.qle4, 4, 1)
        grid.addWidget(self.label5, 5, 0)
        grid.addWidget(self.qle5, 5, 1)
        grid.addWidget(self.label6, 6, 0)
        grid.addWidget(self.qle6, 6, 1)
        grid.addWidget(self.label7, 7, 0)
        grid.addWidget(self.qle7, 7, 1)
        grid.addWidget(self.label8, 8, 0)
        # grid.addWidget(self.textEdit, 8, 1, 2, 1)
        grid.addWidget(self.textEdit, 8, 1)
        grid.addWidget(self.label9, 9, 0)
        grid.addWidget(self.pbar, 9, 1)

        # ================主布局================
        vbox = QVBoxLayout()

        vbox.addLayout(buttonlayout)

        vbox.addWidget(self.cb1)
        vbox.addWidget(self.cb2)

        vbox.addLayout(rbtnlayout)

        # vbox.addWidget(self.label2)

        vbox.addLayout(grid)

        # vbox.addStretch(1)

        # ================窗口设置================
        # self.setGeometry(200, 200, 300, 300)
        layout_widget = QWidget()  # create QWidget object
        layout_widget.setLayout(vbox)  # set layout
        self.setCentralWidget(layout_widget)  # make QWidget the central widget
        self.setWindowTitle(app_name)

        # self.resize(250, 150)
        self.center()
        self.show()

    def onStartButton(self):
        # ================确认变量================
        self.GitHubPathStr = self.qle1.text()
        self.owner = self.qle2.text()
        self.repo_name = self.qle3.text()
        self.export_type = self.btngroup.checkedButton().text()
        self.display_comments = self.cb1.isChecked()  # 是否在博文中显示历史评论
        self.force_replace_url = self.cb2.isChecked()  # 是否强制转换图片网址
        self.start_time = time.time()  # 初始时间戳
        self.log_text = ''

        infos = [self.GitHubPathStr, self.owner, self.repo_name, self.export_type, self.display_comments,
                 self.force_replace_url]
        # ================禁止使用按钮================
        self.button.setEnabled(False)
        self.cb1.setEnabled(False)
        self.cb2.setEnabled(False)
        self.rbtn1.setEnabled(False)
        self.rbtn2.setEnabled(False)
        self.rbtn3.setEnabled(False)
        self.rbtn4.setEnabled(False)
        self.rbtn5.setEnabled(False)

        for info in infos:
            log_line = str(info)
            self.qle7.setText(log_line)
            self.log_text += log_line + '\n'
            self.textEdit.setText(self.log_text)
            self.textEdit.moveCursor(QTextCursor.End)

        self.process_xmls()

        # ================允许使用按钮================
        self.button.setEnabled(True)
        self.cb1.setEnabled(True)
        self.cb2.setEnabled(True)
        self.rbtn1.setEnabled(True)
        self.rbtn2.setEnabled(True)
        self.rbtn3.setEnabled(True)
        self.rbtn4.setEnabled(True)
        self.rbtn5.setEnabled(True)

    def onHello(self):
        self.statusBar().showMessage('你好')
        helloReply = QMessageBox.information(self, '消息', '这是一个消息对话框', QMessageBox.Ok)

    def onAbout(self):
        self.statusBar().showMessage('关于')
        aboutReply = QMessageBox.about(self, '关于', about_me)

    def show_comments(self, state):
        if state == Qt.Checked:
            self.display_comments = True
        else:
            self.display_comments = False

    def on_click(self):
        pass

    # ================控制窗口显示在屏幕中心的方法================
    def center(self):
        # 获得窗口
        qr = self.frameGeometry()
        # 获得屏幕中心点
        cp = QDesktopWidget().availableGeometry().center()
        # 显示到屏幕中心
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def get_https_url(self, jpg_url):
        m_server = re.search(p_server, jpg_url)
        jpg_url_https = jpg_url.replace('http://', 'https://', 1)
        jpg_name = Path(jpg_url).name

        if m_server and 'netease.com' in jpg_url:
            server = m_server.group(1)
            jpg_url_https = 'https://' + server + '.nosdn.127.net/img/' + jpg_name

        # ================图床迁移-GitHub================
        down_jpg_name = jpg_name
        if m_server and not Path(jpg_url).stem.isdigit():
            down_jpg_name = 'img_' + jpg_name

        self.GitHub = Path(self.GitHubPathStr)
        self.jpg_dir = self.GitHub / self.repo_name
        jpg_path = self.jpg_dir / down_jpg_name

        if jpg_path.exists() or (self.force_replace_url and self.GitHub != '' and self.repo_name != ''):
            url_segments = [gh_prefix, self.owner, self.repo_name, 'master', down_jpg_name]
            jpg_url_https = 'https://' + '/'.join(url_segments)

        return jpg_url_https

    def markdown_pic(self, match):
        jpg_url = match.group(1)
        jpg_url = jpg_url.split('?')[0]
        jpg_url_https = self.get_https_url(jpg_url)
        string = '\n![](' + jpg_url_https + ')\n'
        return string

    def process_post(self):
        raw_title = self.post['title']

        # ================标题================
        if isinstance(raw_title, list):  # 长文章
            raw_title = raw_title[0]

        if raw_title:
            title = raw_title
        else:
            title = str(self.count + 1)

        # ================时间================
        publishTime = self.post['publishTime']
        modifyTime = publishTime
        if 'modifyTime' in self.post:
            modifyTime = self.post['modifyTime']

        publishDate = int2time(publishTime, formatter='%Y-%m-%d')
        publishTime = int2time(publishTime)
        modifyTime = int2time(modifyTime)

        # ================元数据================
        tag = ''
        if 'tag' in self.post:
            tag = self.post['tag']

        post_type = self.post['type']
        permalink = self.post['permalink']

        categories = [post_type]
        tags = tag.split(',')

        caption = ''
        if 'caption' in self.post:
            caption = self.post['caption']

        embed = {}
        if 'embed' in self.post:
            embed = self.post['embed']
        if embed != {}:
            embed = json.loads(embed)

        raw_content = ''
        md_content = raw_content

        self.post_pic_urls = []

        produce = True  # 是否输出
        # ================文字、长文章================
        if post_type in ['Text', 'Long']:
            if 'content' in self.post and self.post['content']:
                raw_content = self.post['content']
            md_content = re.sub(p_img, self.markdown_pic, raw_content)
            self.post_pic_urls = p_ext_img.findall(raw_content)

        # ================图片================
        elif post_type == 'Photo':
            photoLinks = ''
            if 'photoLinks' in self.post:
                photoLinks = self.post['photoLinks']
            photoLinks = json.loads(photoLinks)  # 将json字符串转换成python对象

            if isinstance(caption, str):
                md_content = caption

            for photoLink in photoLinks:
                if 'raw' in photoLink and isinstance(photoLink['raw'], str):
                    jpg_url = photoLink['raw']
                elif 'orign' in photoLink and isinstance(photoLink['orign'], str):
                    jpg_url = photoLink['orign']
                else:
                    jpg_url = ''
                if jpg_url != '':
                    jpg_url_https = self.get_https_url(jpg_url)
                    md_content += '\n\n![](' + jpg_url_https + ')'
                    self.post_pic_urls.append(jpg_url_https)

        # ================视频================
        elif post_type == 'Video':
            originUrl = ''
            if 'originUrl' in embed:
                originUrl = embed['originUrl']

            if isinstance(caption, str):
                md_content = caption

            if originUrl != '':
                md_content += '\n\n[' + originUrl + '](' + originUrl + ')'

        # ================音乐================
        elif post_type == 'Music':
            listenUrl = ''
            if 'listenUrl' in embed:
                listenUrl = embed['listenUrl']

            song_name = ''
            if 'song_name' in embed:
                song_name = embed['song_name']
            song_name = song_name.replace('%20', ' ')

            if isinstance(caption, str):
                md_content = caption

            if song_name != '' and listenUrl != '':
                md_content += '\n\n[' + song_name + '](' + listenUrl + ')'
            elif song_name != '':
                md_content += '\n\n【' + song_name + '】'

        # ================问答================
        elif post_type == 'Ask':
            produce = False

        # ================如有例外================
        else:
            produce = False

        # html_content = markdown2.markdown(md_content)
        if self.post_pic_urls:
            self.all_pic_urls.extend(self.post_pic_urls)

        html_content = md_content
        html_content = re.sub('!\[(.*)\]\((.+)\)', r'<img src="\2" alt="\1" />', html_content)  # 图片
        html_content = re.sub('\[(.*)\]\((.+)\)', r'<a href="\2">\1</a>', html_content)  # 链接

        html_content = html_content.strip()

        md_full_content = md_content
        html_full_content = html_content
        if 'commentList' in self.post and self.display_comments:
            md_comment_section, html_comment_section = get_comments(self.post, self.id2name_dict)
            md_full_content += md_comment_section
            html_full_content += html_comment_section

        num_prefix = str(self.count + 1).zfill(len(str(len(self.posts)))) + ' '

        if self.export_type == 'Jekyll':
            md_file_stem = publishDate + '-' + safe(title)
        elif self.export_type == 'Gridea':
            md_file_stem = safe(permalink)
        else:  # if export_type in ['Hexo','Hugo']:
            if raw_title:
                md_file_stem = num_prefix + safe(raw_title)
            else:
                md_file_stem = num_prefix + publishTime.replace(':', '-')

        self.md_file_path = self.md_dir / (md_file_stem + '.md')

        head_matter = get_head_matter(self.export_type, title, publishTime, modifyTime, self.author, categories, tags,
                                      permalink)

        text = head_matter + '\n\n' + md_full_content

        if produce:
            # html_full_content = markdown2.markdown(md_content)
            item_str = get_item_str(self.count, title, publishTime, modifyTime, self.author, categories, tags,
                                    permalink, html_full_content)
            self.output_xml += item_str

            if self.export_type != 'Wordpress':
                write_text(self.md_file_path, text)

        log_line = str(self.md_file_path)
        self.qle7.setText(log_line)
        self.log_text += log_line + '\n'
        self.textEdit.setText(self.log_text)
        self.textEdit.moveCursor(QTextCursor.End)

    def process_xmls(self):
        xmls = get_di_xml(current_dir)
        xmls = [x for x in xmls if x.stem.startswith('LOFTER-')]
        for x in range(len(xmls)):
            xml_file_path = xmls[x]
            with open(xml_file_path, mode="r", encoding="utf-8") as fp:
                xml_text = fp.read()

            # 处理特殊字符
            xml_text = re.sub(u"[\x00-\x08\x0b-\x0c\x0e-\x1f]+", u"", xml_text)

            self.doc = xmltodict.parse(xml_text)

            self.id2name_dict = get_id2name_dict(self.doc)

            self.author = '你的lofter昵称'
            m_lofter = re.search(p_lofter, xml_file_path.stem)
            if m_lofter:
                self.author = m_lofter.group(1)

            if self.export_type == 'Wordpress':
                self.md_dir = current_dir
            else:
                md_dir_name = 'markdown-' + self.export_type + '-' + self.author
                self.md_dir = current_dir / md_dir_name
                make_dir(self.md_dir)

            self.qle5.setText(str(xml_file_path))
            self.qle6.setText(str(self.md_dir))

            output_xml_name = self.export_type + '-' + self.author + '.xml'
            self.output_xml_path = current_dir / output_xml_name

            output_txt_name = 'IDM-pictures-' + self.author + '.txt'
            self.output_txt_path = current_dir / output_txt_name

            self.process_xml()

            self.all_pic_urls = deduce_list(self.all_pic_urls)
            self.all_pic_urls = [x.split('?')[0] for x in self.all_pic_urls]
            self.all_pic_urls = [x for x in self.all_pic_urls if 'raw.githubusercontent.com' not in x]
            self.output_pictxt = '\r\n'.join(self.all_pic_urls)
            write_text(self.output_txt_path, self.output_pictxt)

        # ================运行时间计时================
        self.show_run_time = run_time(self.start_time)
        label_str = '程序结束！' + self.show_run_time

        log_line = label_str
        self.qle7.setText(log_line)
        self.log_text += log_line + '\n'
        self.textEdit.setText(self.log_text)
        self.textEdit.moveCursor(QTextCursor.End)

    def process_xml(self):
        self.posts = self.doc['lofterBlogExport']['PostItem']
        if not isinstance(self.posts, list):
            self.posts = [self.posts]

        self.output_xml = header + channel_header
        self.all_pic_urls = []

        for i in range(len(self.posts)):
            self.post = self.posts[i]
            self.count = i

            self.process_post()

            percent = int(100 * (i + 1) / len(self.posts))
            self.pbar.setValue(percent)
            QApplication.processEvents()  # 刷新页面

        self.output_xml += footer
        if self.export_type == 'Wordpress':
            write_text(self.output_xml_path, self.output_xml)


if __name__ == '__main__':
    current_dir = os.path.dirname(os.path.abspath(__file__))
    current_dir = Path(current_dir)

    dirpath = os.getcwd()

    app_name = 'Lofter2Hexo v5.09 by 墨问非名'
    about_me = '这是将Lofter导出的xml转换成给静态博客使用的markdown的软件。'

    app = QApplication(sys.argv)
    ex = MyWindow()
    sys.exit(app.exec_())
