fix dc:title

empty title caused conversion error
This commit is contained in:
Kulikova Svetlana
2021-02-24 10:59:24 +03:00
parent abffa8d301
commit a6338dac5d
4 changed files with 89 additions and 86 deletions

View File

@ -17,9 +17,9 @@ class EPUBFILE_EXPORT CEpubFile
std::wstring m_sTempDir; std::wstring m_sTempDir;
CBookInfo m_oBookInfo; CBookInfo m_oBookInfo;
CBookToc m_oToc;
std::map<std::wstring, CBookItem> m_mapRefs; std::map<std::wstring, CBookItem> m_mapRefs;
CBookToc m_oToc; std::vector<CBookContentItem> m_arContents;
std::vector<CBookContentItem> m_arContents;
public: public:
CEpubFile(); CEpubFile();

View File

@ -39,13 +39,12 @@ std::wstring CBookToc::GetAttributeValue(XmlUtils::CXmlLiteReader& oXmlLiteReade
{ {
while(oXmlLiteReader.MoveToNextAttribute()) while(oXmlLiteReader.MoveToNextAttribute())
{ {
std::wstring _sAttributeName = oXmlLiteReader.GetName(); if (oXmlLiteReader.GetName() == sAttributeName)
if(_sAttributeName == sAttributeName)
{ {
std::wstring sText = oXmlLiteReader.GetText(); std::wstring sText = oXmlLiteReader.GetText();
size_t posLastSlash = sText.rfind(L'/'); size_t posLastSlash = sText.rfind(L'/');
if (posLastSlash != std::wstring::npos) if (posLastSlash != std::wstring::npos)
sText = sText.substr(posLastSlash + 1); sText.erase(0, posLastSlash + 1);
oXmlLiteReader.MoveToElement(); oXmlLiteReader.MoveToElement();
return sText; return sText;
} }
@ -79,7 +78,7 @@ void CBookToc::ReadMap(XmlUtils::CXmlLiteReader& oXmlLiteReader)
structData.sRef = GetAttributeValue(oXmlLiteReader, L"src"); structData.sRef = GetAttributeValue(oXmlLiteReader, L"src");
} }
if(structData.Full()) if (structData.Full())
{ {
m_arData.push_back(structData); m_arData.push_back(structData);
structData.Clear(); structData.Clear();

View File

@ -13,18 +13,18 @@
#include <random> #include <random>
// Заменяет в строке s все символы s1 на s2 // Заменяет в строке s все символы s1 на s2
static void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2)
{ {
size_t pos = s.find(s1); size_t pos = s.find(s1);
size_t l = s2.length(); size_t l = s2.length();
while(pos != std::string::npos) while (pos != std::string::npos)
{ {
s.replace(pos, s1.length(), s2); s.replace(pos, s1.length(), s2);
pos = s.find(s1, pos + l); pos = s.find(s1, pos + l);
} }
} }
static std::wstring GenerateUUID() std::wstring GenerateUUID()
{ {
std::mt19937 oRand(time(0)); std::mt19937 oRand(time(0));
std::wstringstream sstream; std::wstringstream sstream;
@ -74,10 +74,10 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
std::wstring sFileContent; std::wstring sFileContent;
std::wstring sContent; std::wstring sContent;
if(!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/container.xml", sFileContent)) if (!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/container.xml", sFileContent))
return S_FALSE; return S_FALSE;
size_t nContent = sFileContent.find(L"full-path"); size_t nContent = sFileContent.find(L"full-path");
if(nContent != std::wstring::npos) if (nContent != std::wstring::npos)
{ {
nContent += 11; nContent += 11;
sContent = sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent); sContent = sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent);
@ -87,53 +87,44 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
} }
sContent = m_sTempDir + (sContent.empty() ? L"/content.opf" : L'/' + sContent); sContent = m_sTempDir + (sContent.empty() ? L"/content.opf" : L'/' + sContent);
XmlUtils::CXmlLiteReader oXmlLiteReader; XmlUtils::CXmlLiteReader oXmlLiteReader;
if (oXmlLiteReader.FromFile(sContent)) if (!oXmlLiteReader.FromFile(sContent))
return S_FALSE;
oXmlLiteReader.ReadNextNode();
int nParentDepth = oXmlLiteReader.GetDepth();
while (oXmlLiteReader.ReadNextSiblingNode(nParentDepth))
{ {
oXmlLiteReader.ReadNextNode(); std::wstring sName = oXmlLiteReader.GetName();
int nParentDepth = oXmlLiteReader.GetDepth(); size_t nDot = sName.find(L':');
while (oXmlLiteReader.ReadNextSiblingNode(nParentDepth)) if (nDot != std::wstring::npos)
sName.erase(0, nDot + 1);
if (sName == L"metadata")
m_oBookInfo.ReadInfo(oXmlLiteReader);
else if (sName == L"manifest")
{ {
std::wstring sName = oXmlLiteReader.GetName(); int _nParentDepth = oXmlLiteReader.GetDepth();
size_t nDot = sName.find(L':'); while (true)
if(nDot != std::wstring::npos)
sName.erase(0, nDot + 1);
if (sName == L"metadata")
{ {
m_oBookInfo.ReadInfo(oXmlLiteReader); CBookItem oItem;
// #ifdef _DEBUG if (oItem.ReadItem(oXmlLiteReader, _nParentDepth))
// m_oBookInfo.ShowInfo(); m_mapRefs.insert(std::make_pair(oItem.GetID(), oItem));
// #endif else
break;
} }
else if (sName == L"manifest") }
else if (sName == L"spine")
{
int _nParentDepth = oXmlLiteReader.GetDepth();
while (true)
{ {
int _nParentDepth = oXmlLiteReader.GetDepth(); CBookContentItem oContentItem;
while (true) if (oContentItem.ReadContentItem(oXmlLiteReader, _nParentDepth))
{ m_arContents.push_back(oContentItem);
CBookItem oItem; else
if (oItem.ReadItem(oXmlLiteReader, _nParentDepth)) break;
m_mapRefs.insert(std::make_pair(oItem.GetID(), oItem));
else
break;
}
}
else if (sName == L"spine")
{
int _nParentDepth = oXmlLiteReader.GetDepth();
while (true)
{
CBookContentItem oContentItem;
if (oContentItem.ReadContentItem(oXmlLiteReader, _nParentDepth))
m_arContents.push_back(oContentItem);
else
break;
}
} }
} }
} }
else
return S_FALSE;
/* /*
if (!oXmlLiteReader.FromFile(m_sTempDir + L"/toc.ncx")) if (!oXmlLiteReader.FromFile(m_sTempDir + L"/toc.ncx"))
@ -150,9 +141,9 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
CHtmlParams oFileParams; CHtmlParams oFileParams;
oFileParams.SetAuthors(m_oBookInfo.GetCreators()); oFileParams.SetAuthors(m_oBookInfo.GetCreators());
oFileParams.SetGenres(m_oBookInfo.GetSubjects()); oFileParams.SetGenres (m_oBookInfo.GetSubjects());
oFileParams.SetTitle(m_oBookInfo.GetTitle()); oFileParams.SetTitle (m_oBookInfo.GetTitle());
oFileParams.SetDate(m_oBookInfo.GetDate()); oFileParams.SetDate (m_oBookInfo.GetDate());
oFileParams.SetDescription(m_oBookInfo.GetDescriptions()); oFileParams.SetDescription(m_oBookInfo.GetDescriptions());
oFileParams.SetPageBreakBefore(true); oFileParams.SetPageBreakBefore(true);
@ -304,8 +295,14 @@ HRESULT CEpubFile::FromHtml(const std::wstring& sSrc, const std::wstring& sDstFi
bWasIdentifier = true; bWasIdentifier = true;
else if (sName == L"dc:title") else if (sName == L"dc:title")
{ {
sOut.erase(0, sOut.find(L'>') + 1); size_t nBegin = sOut.find(L'>');
sOut.erase(sOut.find(L'<')); if (nBegin == std::wstring::npos)
continue;
sOut.erase(0, nBegin + 1);
nBegin = sOut.find(L'<');
if (nBegin == std::wstring::npos)
continue;
sOut.erase(nBegin);
sTitle = sOut; sTitle = sOut;
} }
} }

View File

@ -16,6 +16,7 @@ void getDirectories(const std::wstring& sDirectory, std::vector<std::wstring>& a
int main() int main()
{ {
bool bBatchMode = false; bool bBatchMode = false;
bool bFromHtml = false;
if (bBatchMode) if (bBatchMode)
{ {
// Директория файлов // Директория файлов
@ -39,38 +40,44 @@ int main()
for (std::wstring sD : arrDirectory) for (std::wstring sD : arrDirectory)
{ {
std::vector<std::wstring> arrFiles = NSDirectory::GetFiles(sD); if (bFromHtml)
// Директория, где будем создавать docx
size_t nPos = sD.find(L"/fb2");
sD.insert(nPos + 4, L"-res");
NSDirectory::DeleteDirectory(sD);
NSDirectory::CreateDirectory(sD);
for(const std::wstring& sFile : arrFiles)
{ {
CFb2File oFile; }
std::wstring sFileName = NSFile::GetFileName(sFile); else
std::wcout << sFileName << std::endl; {
if(!oFile.IsFb2File(sFile)) std::vector<std::wstring> arrFiles = NSDirectory::GetFiles(sD);
{
nErrorCol++;
arrError.push_back(sFileName);
std::cout << "This isn't a fb2 file" << std::endl;
continue;
}
if(oFile.Open(sFile, sTmp, &oParams) == S_OK) // Директория, где будем создавать docx
size_t nPos = sD.find(L"/fb2");
sD.insert(nPos + 4, L"-res");
NSDirectory::DeleteDirectory(sD);
NSDirectory::CreateDirectory(sD);
for(const std::wstring& sFile : arrFiles)
{ {
std::cout << "Success" << std::endl; CFb2File oFile;
oZip.CompressFileOrDirectory(sTmp, sD + L"/" + sFileName + L".docx"); std::wstring sFileName = NSFile::GetFileName(sFile);
NSDirectory::DeleteDirectory(sTmp + L"/word/media"); std::wcout << sFileName << std::endl;
} if(!oFile.IsFb2File(sFile))
else {
{ nErrorCol++;
nErrorCol++; arrError.push_back(sFileName);
arrError.push_back(sFileName); std::cout << "This isn't a fb2 file" << std::endl;
std::cout << "Failure" << std::endl; continue;
}
if(oFile.Open(sFile, sTmp, &oParams) == S_OK)
{
std::cout << "Success" << std::endl;
oZip.CompressFileOrDirectory(sTmp, sD + L"/" + sFileName + L".docx");
NSDirectory::DeleteDirectory(sTmp + L"/word/media");
}
else
{
nErrorCol++;
arrError.push_back(sFileName);
std::cout << "Failure" << std::endl;
}
} }
} }
} }
@ -84,17 +91,17 @@ int main()
CFb2File oFile; CFb2File oFile;
// Файл, который открываем // Файл, который открываем
std::wstring sFile = NSFile::GetProcessDirectory() + L"/../../../examples/test2.fb2"; std::wstring sFile = NSFile::GetProcessDirectory() + L"/../../../examples/8-sezon-groz.fb2";
// Директория, где будем создавать docx // Директория, где будем создавать docx
std::wstring sOutputDirectory = NSFile::GetProcessDirectory() + L"/res"; std::wstring sOutputDirectory = NSFile::GetProcessDirectory() + L"/res";
NSDirectory::DeleteDirectory(sOutputDirectory); NSDirectory::DeleteDirectory(sOutputDirectory);
NSDirectory::CreateDirectory(sOutputDirectory); NSDirectory::CreateDirectory(sOutputDirectory);
bool bFromHtml = true;
if (bFromHtml) if (bFromHtml)
{ {
sFile = NSFile::GetProcessDirectory() + L"/../../../examples/test1"; sFile = NSFile::GetProcessDirectory() + L"/../../../examples/test3";
oFile.FromHtml(sFile, sOutputDirectory + L"/res.fb2"); oFile.FromHtml(sFile, sOutputDirectory + L"/res.fb2");
return 0; return 0;
} }