Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Veeransh14 authored Feb 29, 2024
2 parents b0d2774 + ef14891 commit 4341352
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 163 deletions.
5 changes: 4 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Build-Depends: debhelper-compat (= 13),
pkg-config,
qtbase5-dev,
qtwebengine5-dev,
libkiwix-dev (>= 11.0.0~)
libkiwix-dev (>= 13.0.0), libkiwix-dev (<< 14.0.0),
libzim-dev (>= 9.0.0), libzim-dev (<< 10.0.0),
Standards-Version: 4.5.0
Homepage: https://www.kiwix.org/
Rules-Requires-Root: no
Expand All @@ -16,6 +17,8 @@ Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends}
Description: offline Wikipedia reader
Kiwix is an offline reader and manager for online content
like Wikipedia, Project Gutenberg, or TED Talks.
Kiwix allows you to read and search through offline content
as they were online. Similar to a browser, Kiwix works with
the highly compressed ZIM file format.
Expand Down
4 changes: 2 additions & 2 deletions kiwix-desktop.pro
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,12 @@ unix {
INSTALLS += mime_file
}

PKGCONFIG_CFLAGS = $$system(pkg-config --cflags $$PKGCONFIG_OPTION \"kiwix >= 13.0.0 libzim >= 8.0.0\")
PKGCONFIG_CFLAGS = $$system(pkg-config --cflags $$PKGCONFIG_OPTION \"kiwix >= 13.0.0 kiwix < 14.0.0 libzim >= 9.0.0 libzim < 10.0.0\")

QMAKE_CXXFLAGS += $$PKGCONFIG_CFLAGS
QMAKE_CFLAGS += $$PKGCONFIG_CFLAGS

LIBS += $$system(pkg-config --libs $$PKGCONFIG_OPTION \"kiwix >= 13.0.0 libzim >= 8.0.0\")
LIBS += $$system(pkg-config --libs $$PKGCONFIG_OPTION \"kiwix >= 13.0.0 kiwix < 14.0.0 libzim >= 9.0.0 libzim < 10.0.0\")

RESOURCES += \
resources/kiwix.qrc \
Expand Down
277 changes: 157 additions & 120 deletions src/contentmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@
namespace
{

class ContentManagerError : public std::runtime_error
{
public:
ContentManagerError(const QString& summary, const QString& details)
: std::runtime_error(summary.toStdString())
, m_details(details)
{}

QString summary() const { return QString::fromStdString(what()); }
QString details() const { return m_details; }

private:
QString m_details;
};

void throwDownloadUnavailableError()
{
throw ContentManagerError(gt("download-unavailable"),
gt("download-unavailable-text"));
}

void checkEnoughStorageAvailable(const kiwix::Book& book, QString targetDir)
{
QStorageInfo storage(targetDir);
auto bytesAvailable = storage.bytesAvailable();
if (bytesAvailable == -1 || book.getSize() > (unsigned long long) bytesAvailable) {
throw ContentManagerError(gt("download-storage-error"),
gt("download-storage-error-text"));
}
}

// Opens the directory containing the input file path.
// parent is the widget serving as the parent for the error dialog in case of
// failure.
Expand Down Expand Up @@ -53,7 +84,7 @@ ContentManager::ContentManager(Library* library, kiwix::Downloader* downloader,
// mp_view will be passed to the tab who will take ownership,
// so, we don't need to delete it.
mp_view = new ContentManagerView();
managerModel = new ContentManagerModel(this);
managerModel = new ContentManagerModel(&m_downloads, this);
const auto booksList = getBooksList();
managerModel->setBooksData(booksList);
auto treeView = mp_view->getView();
Expand Down Expand Up @@ -335,149 +366,163 @@ void ContentManager::openBook(const QString &id)
}
}

#define ADD_V(KEY, METH) {if(key==KEY) {values.insert(key, QString::fromStdString((d->METH()))); continue;}}
QMap<QString, QVariant> ContentManager::updateDownloadInfos(QString id, const QStringList &keys)
namespace
{

QString downloadStatus2QString(kiwix::Download::StatusResult status)
{
switch(status){
case kiwix::Download::K_ACTIVE: return "active";
case kiwix::Download::K_WAITING: return "waiting";
case kiwix::Download::K_PAUSED: return "paused";
case kiwix::Download::K_ERROR: return "error";
case kiwix::Download::K_COMPLETE: return "completed";
case kiwix::Download::K_REMOVED: return "removed";
default: return "unknown";
}
}

QString getDownloadInfo(const kiwix::Download& d, const QString& k)
{
if (k == "id") return QString::fromStdString(d.getDid());
if (k == "path") return QString::fromStdString(d.getPath());
if (k == "status") return downloadStatus2QString(d.getStatus());
if (k == "followedBy") return QString::fromStdString(d.getFollowedBy());
if (k == "totalLength") return QString::number(d.getTotalLength());
if (k == "downloadSpeed") return QString::number(d.getDownloadSpeed());
if (k == "verifiedLength") return QString::number(d.getVerifiedLength());
if (k == "completedLength") return QString::number(d.getCompletedLength());
return "";
}

} // unnamed namespace

void ContentManager::downloadStarted(const kiwix::Book& book, const std::string& downloadId)
{
kiwix::Book bookCopy(book);
bookCopy.setDownloadId(downloadId);
mp_library->addBookToLibrary(bookCopy);
mp_library->save();
emit(oneBookChanged(QString::fromStdString(book.getId())));
}

void ContentManager::downloadCancelled(QString bookId)
{
kiwix::Book bCopy(mp_library->getBookById(bookId));
bCopy.setDownloadId("");
mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy);
mp_library->save();
emit(mp_library->booksChanged());
}

void ContentManager::downloadCompleted(QString bookId, QString path)
{
kiwix::Book bCopy(mp_library->getBookById(bookId));
bCopy.setPath(QDir::toNativeSeparators(path).toStdString());
bCopy.setDownloadId("");
bCopy.setPathValid(true);
// removing book url so that download link in kiwix-serve is not displayed.
bCopy.setUrl("");
mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy);
mp_library->save();
mp_library->bookmarksChanged();
if (!m_local) {
emit(oneBookChanged(bookId));
} else {
emit(mp_library->booksChanged());
}
}

ContentManager::DownloadInfo ContentManager::getDownloadInfo(QString bookId, const QStringList &keys) const
{
QMap<QString, QVariant> values;
DownloadInfo values;
if (!mp_downloader) {
for(auto& key: keys) {
(void) key;
values.insert(key, "");
}
return values;
}
auto& b = mp_library->getBookById(id);

auto& b = mp_library->getBookById(bookId);
std::shared_ptr<kiwix::Download> d;
try {
d = mp_downloader->getDownload(b.getDownloadId());
} catch(...) {
kiwix::Book bCopy(b);
bCopy.setDownloadId("");
mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy);
mp_library->save();
emit(mp_library->booksChanged());
return values;
}

d->updateStatus(true);
if (d->getStatus() == kiwix::Download::K_COMPLETE) {
QString tmp(QString::fromStdString(d->getPath()));
kiwix::Book bCopy(b);
bCopy.setPath(QDir::toNativeSeparators(tmp).toStdString());
bCopy.setDownloadId("");
bCopy.setPathValid(true);
// removing book url so that download link in kiwix-serve is not displayed.
bCopy.setUrl("");
mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy);
mp_library->save();
mp_library->bookmarksChanged();
if (!m_local) {
emit(oneBookChanged(id));
} else {
emit(mp_library->booksChanged());
}
}

for(auto& key: keys){
ADD_V("id", getDid);
if(key == "status") {
switch(d->getStatus()){
case kiwix::Download::K_ACTIVE:
values.insert(key, "active");
break;
case kiwix::Download::K_WAITING:
values.insert(key, "waiting");
break;
case kiwix::Download::K_PAUSED:
values.insert(key, "paused");
break;
case kiwix::Download::K_ERROR:
values.insert(key, "error");
break;
case kiwix::Download::K_COMPLETE:
values.insert(key, "completed");
break;
case kiwix::Download::K_REMOVED:
values.insert(key, "removed");
break;
default:
values.insert(key, "unknown");
}
continue;
}
ADD_V("followedBy", getFollowedBy);
ADD_V("path", getPath);
if(key == "totalLength") {
values.insert(key, QString::number(d->getTotalLength()));
}
if(key == "completedLength") {
values.insert(key, QString::number(d->getCompletedLength()));
}
if(key == "downloadSpeed") {
values.insert(key, QString::number(d->getDownloadSpeed()));
}
if(key == "verifiedLength") {
values.insert(key, QString::number(d->getVerifiedLength()));
}
values.insert(key, ::getDownloadInfo(*d, key));
}

return values;
}
#undef ADD_V

QString ContentManager::downloadBook(const QString &id, QModelIndex index)
ContentManager::DownloadInfo ContentManager::updateDownloadInfos(QString bookId, QStringList keys)
{
QString downloadStatus = downloadBook(id);
QString dialogHeader, dialogText;
if (downloadStatus.size() == 0) {
dialogHeader = gt("download-unavailable");
dialogText = gt("download-unavailable-text");
} else if (downloadStatus == "storage_error") {
dialogHeader = gt("download-storage-error");
dialogText = gt("download-storage-error-text");
} else {
if ( !keys.contains("status") ) keys.append("status");
if ( !keys.contains("path") ) keys.append("path");

const DownloadInfo result = getDownloadInfo(bookId, keys);

if ( result.isEmpty() ) {
downloadCancelled(bookId);
} else if ( result["status"] == "completed" ) {
downloadCompleted(bookId, result["path"].toString());
}

return result;
}

void ContentManager::downloadBook(const QString &id, QModelIndex index)
{
try
{
downloadBook(id);
emit managerModel->startDownload(index);
return downloadStatus;
}
showInfoBox(dialogHeader, dialogText, mp_view);
return downloadStatus;
catch ( const ContentManagerError& err )
{
showInfoBox(err.summary(), err.details(), mp_view);
}
}

const kiwix::Book& ContentManager::getRemoteOrLocalBook(const QString &id)
{
try {
QMutexLocker locker(&remoteLibraryLocker);
return mp_remoteLibrary->getBookById(id.toStdString());
} catch (...) {
return mp_library->getBookById(id);
}
}

QString ContentManager::downloadBook(const QString &id)
void ContentManager::downloadBook(const QString &id)
{
if (!mp_downloader)
return "";
const auto& book = [&]()->const kiwix::Book& {
try {
QMutexLocker locker(&remoteLibraryLocker);
return mp_remoteLibrary->getBookById(id.toStdString());
} catch (...) {
return mp_library->getBookById(id);
}
}();
throwDownloadUnavailableError();

const auto& book = getRemoteOrLocalBook(id);
auto downloadPath = KiwixApp::instance()->getSettingsManager()->getDownloadDir();
QStorageInfo storage(downloadPath);
auto bytesAvailable = storage.bytesAvailable();
if (bytesAvailable == -1 || book.getSize() > (unsigned long long) bytesAvailable) {
return "storage_error";
}
checkEnoughStorageAvailable(book, downloadPath);

auto booksList = mp_library->getBookIds();
for (auto b : booksList)
for (auto b : booksList) {
if (b.toStdString() == book.getId())
return "";
throwDownloadUnavailableError(); // but why???
}

std::shared_ptr<kiwix::Download> download;
try {
std::pair<std::string, std::string> downloadDir("dir", downloadPath.toStdString());
const std::vector<std::pair<std::string, std::string>> options = { downloadDir };
download = mp_downloader->startDownload(book.getUrl(), options);
} catch (std::exception& e) {
return "";
throwDownloadUnavailableError();
}
kiwix::Book bookCopy(book);
bookCopy.setDownloadId(download->getDid());
mp_library->addBookToLibrary(bookCopy);
mp_library->save();
emit(oneBookChanged(id));
return QString::fromStdString(download->getDid());
downloadStarted(book, download->getDid());
}

void ContentManager::eraseBookFilesFromComputer(const QString dirPath, const QString fileName, const bool moveToTrash)
Expand Down Expand Up @@ -556,8 +601,10 @@ void ContentManager::pauseBook(const QString& id)
}
auto& b = mp_library->getBookById(id);
auto download = mp_downloader->getDownload(b.getDownloadId());
if (download->getStatus() == kiwix::Download::K_ACTIVE)
if (download->getStatus() == kiwix::Download::K_ACTIVE) {
download->pauseDownload();
m_downloads[id]->pause();
}
}

void ContentManager::resumeBook(const QString& id, QModelIndex index)
Expand All @@ -573,8 +620,10 @@ void ContentManager::resumeBook(const QString& id)
}
auto& b = mp_library->getBookById(id);
auto download = mp_downloader->getDownload(b.getDownloadId());
if (download->getStatus() == kiwix::Download::K_PAUSED)
if (download->getStatus() == kiwix::Download::K_PAUSED) {
download->resumeDownload();
m_downloads[id]->resume();
}
}

void ContentManager::cancelBook(const QString& id, QModelIndex index)
Expand Down Expand Up @@ -606,18 +655,6 @@ void ContentManager::cancelBook(const QString& id)
emit(oneBookChanged(id));
}

QStringList ContentManager::getDownloadIds()
{
QStringList list;
if (!mp_downloader)
return list;
for(auto& id: mp_downloader->getDownloadIds()) {
qInfo() << QString::fromStdString(id);
list.append(QString::fromStdString(id));
}
return list;
}

void ContentManager::setCurrentLanguage(FilterList langPairList)
{
QStringList languageList;
Expand Down
Loading

0 comments on commit 4341352

Please sign in to comment.