123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- #include "contentmediautils.h"
- #include <QDebug>
- #include <QSet>
- #include <QFileInfo>
- #include <QDir>
- #include <QHash>
- #include <notebookbackend/inotebookbackend.h>
- #include <notebook/node.h>
- #include <buffer/filetypehelper.h>
- #include <vtextedit/markdownutils.h>
- #include <vtextedit/textutils.h>
- #include <utils/pathutils.h>
- #include <utils/fileutils.h>
- #include <core/file.h>
- #include <core/exception.h>
- using namespace vnotex;
- void ContentMediaUtils::copyMediaFiles(Node *p_node,
- INotebookBackend *p_backend,
- const QString &p_destFilePath)
- {
- Q_ASSERT(p_node->hasContent());
- auto file = p_node->getContentFile();
- if (file->getContentType().isMarkdown()) {
- copyMarkdownMediaFiles(file->read(),
- PathUtils::parentDirPath(file->getContentPath()),
- p_backend,
- p_destFilePath);
- }
- }
- void ContentMediaUtils::copyMediaFiles(const QString &p_filePath,
- INotebookBackend *p_backend,
- const QString &p_destFilePath)
- {
- const auto &fileType = FileTypeHelper::getInst().getFileType(p_filePath);
- if (fileType.isMarkdown()) {
- copyMarkdownMediaFiles(FileUtils::readTextFile(p_filePath),
- PathUtils::parentDirPath(p_filePath),
- p_backend,
- p_destFilePath);
- }
- }
- void ContentMediaUtils::copyMediaFiles(const File *p_file,
- const QString &p_destFilePath)
- {
- if (p_file->getContentType().isMarkdown()) {
- copyMarkdownMediaFiles(p_file->read(),
- p_file->getResourcePath(),
- nullptr,
- p_destFilePath);
- }
- }
- void ContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content,
- const QString &p_basePath,
- INotebookBackend *p_backend,
- const QString &p_destFilePath)
- {
- auto content = p_content;
- // Images.
- const auto images =
- vte::MarkdownUtils::fetchImagesFromMarkdownText(content,
- p_basePath,
- vte::MarkdownLink::TypeFlag::LocalRelativeInternal);
- QDir destDir(PathUtils::parentDirPath(p_destFilePath));
- QSet<QString> handledImages;
- QHash<QString, QString> renamedImages;
- int lastPos = content.size();
- for (const auto &link : images) {
- Q_ASSERT(link.m_urlInLinkPos < lastPos);
- lastPos = link.m_urlInLinkPos;
- qDebug() << "link" << link.m_path << link.m_urlInLink;
- if (handledImages.contains(link.m_path)) {
- auto it = renamedImages.find(link.m_path);
- if (it != renamedImages.end()) {
- content.replace(link.m_urlInLinkPos, link.m_urlInLink.size(), it.value());
- }
- continue;
- }
- handledImages.insert(link.m_path);
- if (!QFileInfo::exists(link.m_path)) {
- qWarning() << "image of Markdown file does not exist" << link.m_path << link.m_urlInLink;
- continue;
- }
- // Get the relative path of the image and apply it to the dest file path.
- const auto decodedUrlInLink = vte::TextUtils::decodeUrl(link.m_urlInLink);
- const auto oldDestFilePath = destDir.filePath(decodedUrlInLink);
- destDir.mkpath(PathUtils::parentDirPath(oldDestFilePath));
- auto destFilePath = p_backend ? p_backend->renameIfExistsCaseInsensitive(oldDestFilePath)
- : FileUtils::renameIfExistsCaseInsensitive(oldDestFilePath);
- if (oldDestFilePath != destFilePath) {
- // Rename happens.
- const auto oldFileName = PathUtils::fileName(oldDestFilePath);
- const auto newFileName = PathUtils::fileName(destFilePath);
- qWarning() << QString("image name conflicts when copy, renamed from (%1) to (%2)").arg(oldFileName, newFileName);
- // Update the text content.
- const auto encodedOldFileName = PathUtils::fileName(link.m_urlInLink);
- const auto encodedNewFileName = vte::TextUtils::encodeUrl(newFileName);
- auto newUrlInLink(link.m_urlInLink);
- newUrlInLink.replace(newUrlInLink.size() - encodedOldFileName.size(),
- encodedOldFileName.size(),
- encodedNewFileName);
- content.replace(link.m_urlInLinkPos, link.m_urlInLink.size(), newUrlInLink);
- renamedImages.insert(link.m_path, newUrlInLink);
- }
- if (p_backend) {
- p_backend->copyFile(link.m_path, destFilePath);
- } else {
- FileUtils::copyFile(link.m_path, destFilePath);
- }
- }
- if (!renamedImages.isEmpty()) {
- if (p_backend) {
- p_backend->writeFile(p_destFilePath, content);
- } else {
- FileUtils::writeFile(p_destFilePath, content);
- }
- }
- }
- void ContentMediaUtils::removeMediaFiles(Node *p_node)
- {
- Q_ASSERT(p_node->hasContent());
- auto file = p_node->getContentFile();
- if (file->getContentType().isMarkdown()) {
- removeMarkdownMediaFiles(file.data(), p_node->getBackend());
- }
- }
- void ContentMediaUtils::removeMarkdownMediaFiles(const File *p_file, INotebookBackend *p_backend)
- {
- auto content = p_file->read();
- // Images.
- const auto images =
- vte::MarkdownUtils::fetchImagesFromMarkdownText(content,
- p_file->getResourcePath(),
- vte::MarkdownLink::TypeFlag::LocalRelativeInternal);
- QSet<QString> handledImages;
- for (const auto &link : images) {
- if (handledImages.contains(link.m_path)) {
- continue;
- }
- handledImages.insert(link.m_path);
- if (!QFileInfo::exists(link.m_path)) {
- qWarning() << "image of Markdown file does not exist" << link.m_path << link.m_urlInLink;
- continue;
- }
- p_backend->removeFile(link.m_path);
- }
- }
- void ContentMediaUtils::copyAttachment(Node *p_node,
- INotebookBackend *p_backend,
- const QString &p_destFilePath,
- const QString &p_destAttachmentFolderPath)
- {
- Q_ASSERT(p_node->hasContent());
- Q_ASSERT(!p_node->getAttachmentFolder().isEmpty());
- // Copy the whole folder.
- const auto srcAttachmentFolderPath = p_node->fetchAttachmentFolderPath();
- try {
- if (p_backend) {
- p_backend->copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
- } else {
- FileUtils::copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
- }
- } catch (Exception &e) {
- qWarning() << "failed to copy attachment folder" << srcAttachmentFolderPath << e.what();
- return;
- }
- // Check if we need to modify links in content.
- // FIXME: check the whole relative path.
- if (p_node->getAttachmentFolder() == PathUtils::dirName(p_destAttachmentFolderPath)) {
- return;
- }
- auto file = p_node->getContentFile();
- if (file->getContentType().isMarkdown()) {
- fixMarkdownLinks(srcAttachmentFolderPath, p_backend, p_destFilePath, p_destAttachmentFolderPath);
- }
- }
- void ContentMediaUtils::fixMarkdownLinks(const QString &p_srcFolderPath,
- INotebookBackend *p_backend,
- const QString &p_destFilePath,
- const QString &p_destFolderPath)
- {
- // TODO.
- Q_UNUSED(p_srcFolderPath);
- Q_UNUSED(p_backend);
- Q_UNUSED(p_destFilePath);
- Q_UNUSED(p_destFolderPath);
- }
|