[bookmarks] Export to kmz with custom user symbols.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
parent
906a98ef7b
commit
454338996c
6 changed files with 62 additions and 79 deletions
|
@ -15,7 +15,7 @@ namespace
|
|||
{
|
||||
void CreateAndTestZip(std::string const & filePath, std::string const & zipPath)
|
||||
{
|
||||
TEST(CreateZipFromPathDeflatedAndDefaultCompression(filePath, zipPath), ());
|
||||
TEST(CreateZipFromFiles({filePath}, zipPath, CompressionLevel::DefaultCompression), ());
|
||||
|
||||
ZipFileReader::FileList files;
|
||||
ZipFileReader::FilesList(zipPath, files);
|
||||
|
|
|
@ -67,61 +67,11 @@ int GetCompressionLevel(CompressionLevel compression)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
bool CreateZipFromPathDeflatedAndDefaultCompression(std::string const & filePath,
|
||||
std::string const & zipFilePath)
|
||||
{
|
||||
// Open zip file for writing.
|
||||
SCOPE_GUARD(outFileGuard, [&zipFilePath]() { base::DeleteFileX(zipFilePath); });
|
||||
|
||||
ZipHandle zip(zipFilePath);
|
||||
if (!zip.Handle())
|
||||
return false;
|
||||
|
||||
zip::FileInfo zipInfo = {};
|
||||
CreateTMZip(zipInfo.tmz_date);
|
||||
|
||||
std::string fileName = base::FileNameFromFullPath(filePath);
|
||||
if (!strings::IsASCIIString(fileName))
|
||||
fileName = "OrganicMaps.kml";
|
||||
|
||||
if (zip::Code::Ok != zip::OpenNewFileInZip(zip.Handle(), fileName, zipInfo, "ZIP from OMaps",
|
||||
Z_DEFLATED, Z_DEFAULT_COMPRESSION))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write source file into zip file.
|
||||
try
|
||||
{
|
||||
base::FileData file(filePath, base::FileData::OP_READ);
|
||||
uint64_t const fileSize = file.Size();
|
||||
|
||||
uint64_t currSize = 0;
|
||||
std::array<char, zip::kFileBufferSize> buffer;
|
||||
while (currSize < fileSize)
|
||||
{
|
||||
auto const toRead = std::min(buffer.size(), static_cast<size_t>(fileSize - currSize));
|
||||
file.Read(currSize, buffer.data(), toRead);
|
||||
|
||||
if (zip::Code::Ok != zip::WriteInFileInZip(zip.Handle(), buffer, toRead))
|
||||
return false;
|
||||
|
||||
currSize += toRead;
|
||||
}
|
||||
}
|
||||
catch (Reader::Exception const & ex)
|
||||
{
|
||||
LOG(LERROR, ("Error reading file:", filePath, ex.Msg()));
|
||||
return false;
|
||||
}
|
||||
|
||||
outFileGuard.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateZipFromFiles(std::vector<std::string> const & files, std::string const & zipFilePath,
|
||||
CompressionLevel compression)
|
||||
bool CreateZipFromFiles(std::vector<std::string> const & filePaths, std::string const & zipFilePath,
|
||||
CompressionLevel compression /* = CompressionLevel::DefaultCompression */,
|
||||
std::vector<std::string> const * fileNames /* = nullptr */)
|
||||
{
|
||||
ASSERT(!fileNames || filePaths.size() == fileNames->size(), ());
|
||||
SCOPE_GUARD(outFileGuard, [&zipFilePath]() { base::DeleteFileX(zipFilePath); });
|
||||
|
||||
ZipHandle zip(zipFilePath);
|
||||
|
@ -129,19 +79,21 @@ bool CreateZipFromFiles(std::vector<std::string> const & files, std::string cons
|
|||
return false;
|
||||
|
||||
auto const compressionLevel = GetCompressionLevel(compression);
|
||||
zip::FileInfo const fileInfo = {};
|
||||
|
||||
zip::FileInfo zipInfo = {};
|
||||
CreateTMZip(zipInfo.tmz_date);
|
||||
|
||||
try
|
||||
{
|
||||
for (auto const & filePath : files)
|
||||
for (size_t i = 0; i < filePaths.size(); ++i)
|
||||
{
|
||||
if (zip::Code::Ok != zip::OpenNewFileInZip(zip.Handle(), filePath, fileInfo, "",
|
||||
Z_DEFLATED, compressionLevel))
|
||||
if (zip::Code::Ok != zip::OpenNewFileInZip(zip.Handle(), fileNames ? fileNames->at(i) : filePaths[i],
|
||||
zipInfo, "ZIP from Organic Maps", Z_DEFLATED, compressionLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
base::FileData file(filePath, base::FileData::OP_READ);
|
||||
base::FileData file(filePaths[i], base::FileData::OP_READ);
|
||||
uint64_t const fileSize = file.Size();
|
||||
uint64_t writtenSize = 0;
|
||||
zip::Buffer buffer;
|
||||
|
|
|
@ -12,8 +12,8 @@ enum class CompressionLevel
|
|||
Count
|
||||
};
|
||||
|
||||
bool CreateZipFromPathDeflatedAndDefaultCompression(std::string const & filePath,
|
||||
std::string const & zipFilePath);
|
||||
|
||||
bool CreateZipFromFiles(std::vector<std::string> const & files, std::string const & zipFilePath,
|
||||
CompressionLevel compression = CompressionLevel::DefaultCompression);
|
||||
/// @param[in] filePaths Full paths on disk to archive.
|
||||
/// @param[in] fileNames Correspondent (for filePaths) file names in archive.
|
||||
bool CreateZipFromFiles(std::vector<std::string> const & filePaths, std::string const & zipFilePath,
|
||||
CompressionLevel compression = CompressionLevel::DefaultCompression,
|
||||
std::vector<std::string> const * fileNames = nullptr);
|
||||
|
|
|
@ -81,19 +81,41 @@ BookmarkManager::SharingResult GetFileForSharing(BookmarkManager::KMLDataCollect
|
|||
if (fileName.empty())
|
||||
fileName = base::GetNameFromFullPathWithoutExt(kmlToShare.first);
|
||||
|
||||
auto const filePath = base::JoinPath(GetPlatform().TmpDir(), fileName + std::string{kKmlExtension});
|
||||
SCOPE_GUARD(fileGuard, std::bind(&base::DeleteFileX, filePath));
|
||||
/// @todo Really needed for zip?
|
||||
if (!strings::IsASCIIString(fileName))
|
||||
fileName = kDefaultBookmarksFileName;
|
||||
fileName.append(kKmlExtension);
|
||||
|
||||
auto const & tmpDir = GetPlatform().TmpDir();
|
||||
std::vector<std::string> filePaths, fileNames;
|
||||
fileNames.push_back(fileName);
|
||||
filePaths.push_back(base::JoinPath(tmpDir, fileNames.back()));
|
||||
SCOPE_GUARD(fileGuard, std::bind(&base::DeleteFileX, filePaths.back()));
|
||||
|
||||
auto const categoryId = kmlToShare.second->m_categoryData.m_id;
|
||||
|
||||
if (!SaveKmlFileSafe(*kmlToShare.second, filePath, KmlFileType::Text))
|
||||
if (!SaveKmlFileSafe(*kmlToShare.second, filePaths.back(), KmlFileType::Text))
|
||||
return {categoryId, BookmarkManager::SharingResult::Code::FileError, "Bookmarks file does not exist."};
|
||||
|
||||
auto const tmpFilePath = base::JoinPath(GetPlatform().TmpDir(), fileName + std::string{kKmzExtension});
|
||||
if (!CreateZipFromPathDeflatedAndDefaultCompression(filePath, tmpFilePath))
|
||||
auto const bookmarksDir = GetBookmarksDirectory();
|
||||
for (auto const & bmData : kmlToShare.second->m_bookmarksData)
|
||||
{
|
||||
if (!bmData.m_iconPath.empty())
|
||||
{
|
||||
auto const path = base::JoinPath(bookmarksDir, bmData.m_iconPath);
|
||||
if (Platform::IsFileExistsByFullPath(path))
|
||||
{
|
||||
fileNames.push_back(bmData.m_iconPath);
|
||||
filePaths.push_back(std::move(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto const kmzFilePath = base::JoinPath(tmpDir, fileName);
|
||||
if (!CreateZipFromFiles(filePaths, kmzFilePath, CompressionLevel::DefaultCompression, &fileNames))
|
||||
return {categoryId, BookmarkManager::SharingResult::Code::ArchiveError, "Could not create archive."};
|
||||
|
||||
return {categoryId, tmpFilePath};
|
||||
return {categoryId, kmzFilePath};
|
||||
}
|
||||
|
||||
std::string ToString(BookmarkManager::SortingType type)
|
||||
|
@ -2196,7 +2218,7 @@ kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(kml::CategoryData && da
|
|||
return groupId;
|
||||
}
|
||||
|
||||
kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(std::string const & name, bool autoSave)
|
||||
kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(std::string const & name, bool autoSave /* = true */)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
auto const groupId = UserMarkIdStorage::Instance().GetNextCategoryId();
|
||||
|
@ -2557,6 +2579,7 @@ std::unique_ptr<kml::FileData> BookmarkManager::CollectBmGroupKMLData(BookmarkCa
|
|||
return kmlData;
|
||||
}
|
||||
|
||||
/*
|
||||
bool BookmarkManager::SaveBookmarkCategory(kml::MarkGroupId groupId)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
|
@ -2576,6 +2599,7 @@ bool BookmarkManager::SaveBookmarkCategory(kml::MarkGroupId groupId, Writer & wr
|
|||
auto kmlData = CollectBmGroupKMLData(group);
|
||||
return SaveKmlData(*kmlData, writer, fileType);
|
||||
}
|
||||
*/
|
||||
|
||||
BookmarkManager::KMLDataCollectionPtr BookmarkManager::PrepareToSaveBookmarks(
|
||||
kml::GroupIdCollection const & groupIdCollection)
|
||||
|
|
|
@ -360,9 +360,11 @@ public:
|
|||
void FilterInvalidBookmarks(kml::MarkIdCollection & bookmarks) const;
|
||||
void FilterInvalidTracks(kml::TrackIdCollection & tracks) const;
|
||||
|
||||
/// @todo Avoid dualism with sync/async tasks. Leave async only.
|
||||
void EnableTestMode(bool enable);
|
||||
bool SaveBookmarkCategory(kml::MarkGroupId groupId);
|
||||
bool SaveBookmarkCategory(kml::MarkGroupId groupId, Writer & writer, KmlFileType fileType) const;
|
||||
|
||||
// bool SaveBookmarkCategory(kml::MarkGroupId groupId);
|
||||
// bool SaveBookmarkCategory(kml::MarkGroupId groupId, Writer & writer, KmlFileType fileType) const;
|
||||
|
||||
static void UpdateLastModifiedTime(KMLDataCollection & collection);
|
||||
// Used for LoadBookmarks() and unit tests only. Does *not* update last modified time.
|
||||
|
|
|
@ -211,6 +211,7 @@ UNIT_CLASS_TEST(Runner, Bookmarks_ImportKML)
|
|||
TEST_EQUAL(bmManager.IsVisible(groupId), false, ());
|
||||
}
|
||||
|
||||
/*
|
||||
UNIT_CLASS_TEST(Runner, Bookmarks_ExportKML)
|
||||
{
|
||||
string const dir = GetBookmarksDirectory();
|
||||
|
@ -268,7 +269,7 @@ UNIT_CLASS_TEST(Runner, Bookmarks_ExportKML)
|
|||
kmlDataCollection3.emplace_back(fileName, LoadKmlFile(fileName, GetActiveKmlFileType()));
|
||||
TEST(kmlDataCollection3.back().second, ());
|
||||
|
||||
bmManager.CreateCategories(std::move(kmlDataCollection3), true /* autoSave */);
|
||||
bmManager.CreateCategories(std::move(kmlDataCollection3), true);
|
||||
TEST_EQUAL(bmManager.GetBmGroupsIdList().size(), 1, ());
|
||||
|
||||
auto const groupId3 = bmManager.GetBmGroupsIdList().front();
|
||||
|
@ -279,6 +280,7 @@ UNIT_CLASS_TEST(Runner, Bookmarks_ExportKML)
|
|||
uint64_t dummy;
|
||||
TEST(base::GetFileSize(fileName, dummy), ());
|
||||
}
|
||||
*/
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -967,12 +969,13 @@ UNIT_CLASS_TEST(Runner, Bookmarks_InnerFolder)
|
|||
TEST_EQUAL(bmManager.GetUserMarkIds(groupIds.front()).size(), 1, ());
|
||||
}
|
||||
|
||||
/*
|
||||
UNIT_CLASS_TEST(Runner, BookmarkCategory_EmptyName)
|
||||
{
|
||||
BookmarkManager bmManager(BM_CALLBACKS);
|
||||
bmManager.EnableTestMode(true);
|
||||
|
||||
auto const catId = bmManager.CreateBookmarkCategory("", false /* autoSave */);
|
||||
auto const catId = bmManager.CreateBookmarkCategory("", false);
|
||||
kml::BookmarkData bm;
|
||||
bm.m_point = m2::PointD(0, 0);
|
||||
bmManager.GetEditSession().CreateBookmark(std::move(bm), catId);
|
||||
|
@ -986,6 +989,7 @@ UNIT_CLASS_TEST(Runner, BookmarkCategory_EmptyName)
|
|||
vector<string> const arrFiles = {"Bookmarks", "xxx"};
|
||||
DeleteCategoryFiles(arrFiles);
|
||||
}
|
||||
*/
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -1046,6 +1050,7 @@ UNIT_CLASS_TEST(Runner, Bookmarks_SpecialXMLNames)
|
|||
expectedName = "test";
|
||||
bmManager.GetEditSession().SetCategoryName(catId, expectedName);
|
||||
|
||||
/*
|
||||
TEST(bmManager.SaveBookmarkCategory(catId), ());
|
||||
|
||||
auto const fileName = bmManager.GetCategoryFileName(catId);
|
||||
|
@ -1055,12 +1060,11 @@ UNIT_CLASS_TEST(Runner, Bookmarks_SpecialXMLNames)
|
|||
bmManager.GetEditSession().DeleteBmCategory(catId);
|
||||
|
||||
BookmarkManager::KMLDataCollection kmlDataCollection2;
|
||||
kmlDataCollection2.emplace_back("" /* filePath */, LoadKmlFile(fileNameTmp, GetActiveKmlFileType()));
|
||||
kmlDataCollection2.emplace_back("", LoadKmlFile(fileNameTmp, GetActiveKmlFileType()));
|
||||
bmManager.CreateCategories(std::move(kmlDataCollection2));
|
||||
|
||||
BookmarkManager::KMLDataCollection kmlDataCollection3;
|
||||
kmlDataCollection3.emplace_back("" /* filePath */,
|
||||
LoadKmlData(MemReader(kmlString3, strlen(kmlString3)), KmlFileType::Text));
|
||||
kmlDataCollection3.emplace_back("", LoadKmlData(MemReader(kmlString3, strlen(kmlString3)), KmlFileType::Text));
|
||||
|
||||
bmManager.UpdateLastModifiedTime(kmlDataCollection3);
|
||||
bmManager.CreateCategories(std::move(kmlDataCollection3));
|
||||
|
@ -1081,6 +1085,7 @@ UNIT_CLASS_TEST(Runner, Bookmarks_SpecialXMLNames)
|
|||
TEST_EQUAL(kml::GetDefaultStr(bm1->GetName()), "![X1]{X2}(X3)", ());
|
||||
|
||||
TEST(base::DeleteFileX(fileNameTmp), ());
|
||||
*/
|
||||
}
|
||||
|
||||
UNIT_CLASS_TEST(Runner, TrackParsingTest_1)
|
||||
|
|
Reference in a new issue