Commit a2e009dd authored by Oleg.Korshul's avatar Oleg.Korshul Committed by Alexander Trofimov

Epub file realize

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63917 954022d7-b5bf-4e40-9824-e11837661b57
parent 6ba500ca
...@@ -206,6 +206,7 @@ namespace XmlUtils ...@@ -206,6 +206,7 @@ namespace XmlUtils
CXmlNode ReadNode(const wchar_t* strNodeName); CXmlNode ReadNode(const wchar_t* strNodeName);
CXmlNode ReadNode(const std::wstring& strNodeName); CXmlNode ReadNode(const std::wstring& strNodeName);
CXmlNode ReadNodeNoNS(const std::wstring& strNodeName); CXmlNode ReadNodeNoNS(const std::wstring& strNodeName);
CXmlNodes ReadNodesNoNS(const std::wstring& strNodeName);
CXmlNode GetNode(const std::wstring& sName); CXmlNode GetNode(const std::wstring& sName);
CXmlNodes GetNodes(const std::wstring& sName); CXmlNodes GetNodes(const std::wstring& sName);
......
...@@ -559,6 +559,29 @@ namespace XmlUtils ...@@ -559,6 +559,29 @@ namespace XmlUtils
} }
return node; return node;
} }
CXmlNodes CXmlNode::ReadNodesNoNS(const std::wstring& sName)
{
CXmlNodes oNodes;
if (IsValid())
{
bool bGetAll = false;
if (L"*" == sName)
bGetAll = true;
int nCount = (int)m_pBase->m_nodes.size();
for (int i = 0; i < nCount; ++i)
{
if (bGetAll || sName == GetNameNoNS(m_pBase->m_nodes[i]->m_sName))
{
CXmlNode oNode;
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
oNode.SetBase(pBase);
oNodes.m_nodes.insert(oNodes.m_nodes.end(), oNode);
}
}
}
return oNodes;
}
CXmlNode CXmlNode::GetNode(const std::wstring& sName) CXmlNode CXmlNode::GetNode(const std::wstring& sName)
{ {
......
#include "HtmlFile.h" #include "HtmlFile.h"
#include "../DesktopEditor/common/File.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 #ifdef LINUX
#include <unistd.h> #include <unistd.h>
...@@ -125,3 +131,237 @@ int CHtmlFile::Convert(const std::wstring& sXml, const std::wstring& sPathIntern ...@@ -125,3 +131,237 @@ int CHtmlFile::Convert(const std::wstring& sXml, const std::wstring& sPathIntern
NSFile::CFileBinary::Remove(sTempFileForParams); NSFile::CFileBinary::Remove(sTempFileForParams);
return nReturnCode; 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);
}
...@@ -33,6 +33,16 @@ public: ...@@ -33,6 +33,16 @@ public:
/// \return 1 error, 0 - success /// \return 1 error, 0 - success
/// ///
int Convert(const std::wstring& sXml, const std::wstring& sPathInternal = L""); int Convert(const std::wstring& sXml, const std::wstring& sPathInternal = L"");
///
/// \brief ConvertEpub
/// \param sFolder - unzip folder (slash or without slash)
/// \param sMetaInfo - epub meta data
/// \param sXmlPart - <sdk>file:///D:/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb/Word/sdk-all.js</sdk><destination>D:/test/Document/</destination> (end /!!!)
/// \param sPathInternal - like Convert html
/// \return 1 error, 0 - success
///
int ConvertEpub(const std::wstring& sFolder, std::wstring& sMetaInfo, const std::wstring& sXmlPart, const std::wstring& sPathInternal = L"");
}; };
#endif // _HTMLFILE_HTMLFILE_H_ #endif // _HTMLFILE_HTMLFILE_H_
...@@ -45,7 +45,8 @@ linux-g++:!contains(QMAKE_HOST.arch, x86_64):{ ...@@ -45,7 +45,8 @@ linux-g++:!contains(QMAKE_HOST.arch, x86_64):{
shared { shared {
DEFINES += HTMLFILE_USE_DYNAMIC_LIBRARY DEFINES += HTMLFILE_USE_DYNAMIC_LIBRARY
LIBS += -L$$DESTDIR -llibxml LIB_XML_PRI_PATH = ../DesktopEditor/xml
include(../DesktopEditor/xml/build/qt/libxml2.pri)
message(dynamic) message(dynamic)
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#if 0
#ifdef WIN32 #ifdef WIN32
std::wstring sPath = NSFile::GetProcessDirectory() + L"/../../Internal/windows/Release/"; std::wstring sPath = NSFile::GetProcessDirectory() + L"/../../Internal/windows/Release/";
...@@ -29,5 +31,33 @@ int main(int argc, char *argv[]) ...@@ -29,5 +31,33 @@ int main(int argc, char *argv[])
int nResult = oFile.Convert(sXml, sPath); int nResult = oFile.Convert(sXml, sPath);
nResult; nResult;
#else
#ifdef WIN32
std::wstring sPath = NSFile::GetProcessDirectory() + L"/../../Internal/windows/Release/";
std::wstring sXml = L"\
<sdk>file:///D:/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb/Word/sdk-all.js</sdk>\
<destination>D:/test/Document/</destination>\
";
#else
std::wstring sPath = NSFile::GetProcessDirectory() + L"/../../Internal/linux/Release/";
std::wstring sXml = L"\
<html>\
<sdk>file:///home/oleg/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb/Word/sdk-all.js</sdk>\
<file>file:///home/oleg/activex/test.html</file>\
<destination>/home/oleg/activex/1/</destination>\
</html>\
";
#endif
CHtmlFile oFile;
std::wstring sMetaInfo;
int nResult = oFile.ConvertEpub(L"D:\\37898EB", sMetaInfo, sXml, sPath);
nResult;
#endif
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment