mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-19 00:28:22 +08:00
Epub file realize
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63917 954022d7-b5bf-4e40-9824-e11837661b57
This commit is contained in:
committed by
Alexander Trofimov
parent
6ba500ca61
commit
a2e009dd20
@ -1,5 +1,11 @@
|
||||
#include "HtmlFile.h"
|
||||
#include "../DesktopEditor/common/File.h"
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
#include "../DesktopEditor/common/String.h"
|
||||
#include "../DesktopEditor/xml/include/xmlutils.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#ifdef LINUX
|
||||
#include <unistd.h>
|
||||
@ -125,3 +131,237 @@ int CHtmlFile::Convert(const std::wstring& sXml, const std::wstring& sPathIntern
|
||||
NSFile::CFileBinary::Remove(sTempFileForParams);
|
||||
return nReturnCode;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// EPUB
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
static std::vector<std::wstring> ParseEpub(const std::wstring& sPackagePath, std::wstring& sMetaInfo)
|
||||
{
|
||||
std::vector<std::wstring> arHtmls;
|
||||
|
||||
XmlUtils::CXmlNode oNodeRoot;
|
||||
if (!oNodeRoot.FromXmlFile(sPackagePath))
|
||||
return arHtmls;
|
||||
|
||||
XmlUtils::CXmlNode oNodeMeta = oNodeRoot.ReadNodeNoNS(L"metadata");
|
||||
if (oNodeMeta.IsValid())
|
||||
{
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
|
||||
std::wstring sTitle = oNodeMeta.ReadValueString(L"dc:title");
|
||||
std::wstring sCreator = oNodeMeta.ReadValueString(L"dc:creator");
|
||||
std::wstring sPublisher = oNodeMeta.ReadValueString(L"dc:publisher");
|
||||
std::wstring sLanguage = oNodeMeta.ReadValueString(L"dc:language");
|
||||
std::wstring sContributor = oNodeMeta.ReadValueString(L"dc:contributor");
|
||||
std::wstring sDescription = oNodeMeta.ReadValueString(L"dc:description");
|
||||
std::wstring sCoverage = oNodeMeta.ReadValueString(L"dc:coverage");
|
||||
|
||||
XmlUtils::CXmlNodes oMetaNodes = oNodeMeta.ReadNodesNoNS(L"meta");
|
||||
if (oMetaNodes.IsValid())
|
||||
{
|
||||
int nCountMeta = oMetaNodes.GetCount();
|
||||
for (int i = 0; i < nCountMeta; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oNodeTmp;
|
||||
oMetaNodes.GetAt(i, oNodeTmp);
|
||||
|
||||
std::wstring sName = oNodeTmp.GetAttribute(L"name");
|
||||
if (sName == L"cover")
|
||||
sCoverage = L"1";
|
||||
}
|
||||
}
|
||||
|
||||
if (!sTitle.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<name>");
|
||||
oBuilder.WriteEncodeXmlString(sTitle.c_str(), (int)sTitle.length());
|
||||
oBuilder.WriteString(L"</name>");
|
||||
}
|
||||
if (!sCreator.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<author>");
|
||||
oBuilder.WriteEncodeXmlString(sCreator.c_str(), (int)sCreator.length());
|
||||
oBuilder.WriteString(L"</author>");
|
||||
|
||||
oBuilder.WriteString(L"<creator>");
|
||||
oBuilder.WriteEncodeXmlString(sCreator.c_str(), (int)sCreator.length());
|
||||
oBuilder.WriteString(L"</creator>");
|
||||
}
|
||||
if (!sPublisher.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<publisher>");
|
||||
oBuilder.WriteEncodeXmlString(sPublisher.c_str(), (int)sPublisher.length());
|
||||
oBuilder.WriteString(L"</publisher>");
|
||||
}
|
||||
if (!sLanguage.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<language>");
|
||||
oBuilder.WriteEncodeXmlString(sLanguage.c_str(), (int)sLanguage.length());
|
||||
oBuilder.WriteString(L"</language>");
|
||||
}
|
||||
if (!sContributor.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<creator>");
|
||||
oBuilder.WriteEncodeXmlString(sContributor.c_str(), (int)sContributor.length());
|
||||
oBuilder.WriteString(L"</creator>");
|
||||
}
|
||||
if (!sDescription.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<annotation>");
|
||||
oBuilder.WriteEncodeXmlString(sDescription.c_str(), (int)sDescription.length());
|
||||
oBuilder.WriteString(L"</annotation>");
|
||||
}
|
||||
if (!sCoverage.empty())
|
||||
{
|
||||
oBuilder.WriteString(L"<coverpage>1</coverpage>");
|
||||
}
|
||||
|
||||
if (0 != oBuilder.GetCurSize())
|
||||
sMetaInfo = L"<meta>" + oBuilder.GetData() + L"</meta>";
|
||||
}
|
||||
|
||||
XmlUtils::CXmlNode oNodeSpine = oNodeRoot.ReadNodeNoNS(L"spine");
|
||||
if (!oNodeRoot.IsValid())
|
||||
return arHtmls;
|
||||
|
||||
XmlUtils::CXmlNodes oNodesItemRef = oNodeSpine.ReadNodesNoNS(L"itemref");
|
||||
if (!oNodeSpine.IsValid())
|
||||
return arHtmls;
|
||||
|
||||
std::vector<std::wstring> sIds;
|
||||
int nCountRefs = oNodesItemRef.GetCount();
|
||||
for (int i = 0; i < nCountRefs; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oNodeTmp;
|
||||
oNodesItemRef.GetAt(i, oNodeTmp);
|
||||
|
||||
std::wstring sId = oNodeTmp.GetAttribute(L"idref");
|
||||
if (!sId.empty())
|
||||
sIds.push_back(sId);
|
||||
}
|
||||
|
||||
if (0 == sIds.size())
|
||||
return arHtmls;
|
||||
|
||||
XmlUtils::CXmlNode oNodeManifest = oNodeRoot.ReadNodeNoNS(L"manifest");
|
||||
if (!oNodeRoot.IsValid())
|
||||
return arHtmls;
|
||||
XmlUtils::CXmlNodes oNodesItems = oNodeManifest.ReadNodesNoNS(L"item");
|
||||
if (!oNodeManifest.IsValid())
|
||||
return arHtmls;
|
||||
|
||||
size_t pos = sPackagePath.find_last_of((wchar_t)'/');
|
||||
std::wstring sPackagePathDir = sPackagePath;
|
||||
if (std::wstring::npos != pos)
|
||||
sPackagePathDir = sPackagePath.substr(0, pos + 1);
|
||||
|
||||
std::map<std::wstring, std::wstring> mapHtmls;
|
||||
int nCountItems = oNodesItems.GetCount();
|
||||
for (int i = 0; i < nCountItems; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oNodeTmp;
|
||||
oNodesItems.GetAt(i, oNodeTmp);
|
||||
|
||||
std::wstring sMime = oNodeTmp.GetAttribute(L"media-type");
|
||||
std::wstring sHRef = oNodeTmp.GetAttribute(L"href");
|
||||
|
||||
#if 0
|
||||
//Decode URL
|
||||
sHRef.Replace(_T("%20"), _T(" "));
|
||||
sHRef.Replace(_T("%3B"), _T(";"));
|
||||
sHRef.Replace(_T("%2C"), _T(","));
|
||||
sHRef.Replace(_T("%26"), _T("&"));
|
||||
sHRef.Replace(_T("%3D"), _T("="));
|
||||
sHRef.Replace(_T("%2B"), _T("+"));
|
||||
sHRef.Replace(_T("%24"), _T("$"));
|
||||
#endif
|
||||
|
||||
std::wstring sId = oNodeTmp.GetAttribute(L"id");
|
||||
if (!sMime.empty() && !sHRef.empty())
|
||||
mapHtmls.insert(std::pair<std::wstring, std::wstring>(sId, sPackagePathDir + sHRef));
|
||||
}
|
||||
|
||||
for (std::vector<std::wstring>::iterator iter = sIds.begin(); iter != sIds.end(); iter++)
|
||||
{
|
||||
std::map<std::wstring, std::wstring>::const_iterator i = mapHtmls.find(*iter);
|
||||
if (i != mapHtmls.end())
|
||||
{
|
||||
arHtmls.push_back(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
return arHtmls;
|
||||
}
|
||||
|
||||
int CHtmlFile::ConvertEpub(const std::wstring& sFolder, std::wstring& sMetaInfo, const std::wstring& sXmlPart, const std::wstring& sPathInternal)
|
||||
{
|
||||
std::wstring sFolderWithSlash = sFolder;
|
||||
NSStringExt::Replace(sFolderWithSlash, L"\\", L"/");
|
||||
|
||||
if (!sFolderWithSlash.empty())
|
||||
{
|
||||
wchar_t c = sFolderWithSlash.c_str()[sFolderWithSlash.length() - 1];
|
||||
if (c != '/' && c != '\\')
|
||||
sFolderWithSlash += L"/";
|
||||
}
|
||||
|
||||
std::wstring sMimeType = L"";
|
||||
if (!NSFile::CFileBinary::ReadAllTextUtf8(sFolderWithSlash + L"mimetype", sMimeType))
|
||||
return 1;
|
||||
|
||||
if (sMimeType != L"application/epub+zip")
|
||||
return 1;
|
||||
|
||||
std::wstring sContainer = sFolderWithSlash + L"META-INF/container.xml";
|
||||
XmlUtils::CXmlNode oNodeContainer;
|
||||
if (!oNodeContainer.FromXmlFile(sContainer))
|
||||
return 1;
|
||||
|
||||
XmlUtils::CXmlNode oNodeRootFiles = oNodeContainer.ReadNodeNoNS(L"rootfiles");
|
||||
if (!oNodeRootFiles.IsValid())
|
||||
return 1;
|
||||
|
||||
std::wstring sPackagePathXml;
|
||||
|
||||
XmlUtils::CXmlNodes oNodesRootFile = oNodeRootFiles.ReadNodesNoNS(L"rootfile");
|
||||
if (!oNodeRootFiles.IsValid())
|
||||
return 1;
|
||||
|
||||
int nCount = oNodesRootFile.GetCount();
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oNodeRF;
|
||||
oNodesRootFile.GetAt(i, oNodeRF);
|
||||
|
||||
std::wstring sMime = oNodeRF.GetAttribute(L"media-type");
|
||||
std::wstring sPackagePath = oNodeRF.GetAttribute(L"full-path");
|
||||
|
||||
if (!sPackagePath.empty() && L"application/oebps-package+xml" == sMime)
|
||||
sPackagePathXml = sFolderWithSlash + sPackagePath;
|
||||
}
|
||||
|
||||
if (sPackagePathXml.empty())
|
||||
return 1;
|
||||
|
||||
std::vector<std::wstring> arHtmls = ParseEpub(sPackagePathXml, sMetaInfo);
|
||||
if (arHtmls.size() == 0)
|
||||
return 1;
|
||||
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
for (std::vector<std::wstring>::iterator iter = arHtmls.begin(); iter != arHtmls.end(); iter++)
|
||||
{
|
||||
oBuilder.WriteString(L"<file>", 6);
|
||||
|
||||
wchar_t c = iter->c_str()[0];
|
||||
if (c == '/')
|
||||
oBuilder.WriteString(L"file://", 7);
|
||||
else
|
||||
oBuilder.WriteString(L"file:///", 8);
|
||||
oBuilder.WriteEncodeXmlString(iter->c_str(), iter->length());
|
||||
|
||||
oBuilder.WriteString(L"</file>", 7);
|
||||
}
|
||||
|
||||
return this->Convert(L"<html>" + oBuilder.GetData() + sXmlPart + L"</html>", sPathInternal);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user