void Client::on(DirectoryListingManagerListener::OpenListing, const DirectoryListingPtr& aList, const string& aDir, const string& aXML) noexcept { if (aList->getPartialList()) { aList->addPartialListTask(aXML, aDir, false); } else { aList->addFullListTask(aDir); } }
string FilelistInfo::formatState(const DirectoryListingPtr& aList) noexcept { if (aList->getDownloadState() == DirectoryListing::STATE_DOWNLOADED) { return aList->isLoaded() ? "loaded" : "loading"; } return Serializer::serializeDownloadState(*aList.get()); }
void DirectoryListingManager::on(QueueManagerListener::ItemRemoved, const QueueItemPtr& qi, bool aFinished) noexcept { if (!qi->isSet(QueueItem::FLAG_USER_LIST)) return; auto u = qi->getSources()[0].getUser(); if (qi->isSet(QueueItem::FLAG_DIRECTORY_DOWNLOAD) && !aFinished) removeDirectoryDownload(u, qi->getTempTarget(), qi->isSet(QueueItem::FLAG_PARTIAL_LIST)); if (qi->isSet(QueueItem::FLAG_CLIENT_VIEW)) { DirectoryListingPtr dl = nullptr; { RLock l(cs); auto p = viewedLists.find(u); if (p == viewedLists.end()) { dcassert(0); return; } dl = p->second; } dl->onListRemovedQueue(qi->getTarget(), qi->getTempTarget(), aFinished); bool closing = (dl->getClosing() || !dl->hasCompletedDownloads()); if (!aFinished && !dl->hasDownloads() && closing) { removeList(u); } } }
bool DirectoryListingManager::removeList(const UserPtr& aUser) noexcept { DirectoryListingPtr dl; { RLock l(cs); auto p = viewedLists.find(aUser); if (p == viewedLists.end()) { return false; } dl = p->second; } auto downloads = dl->getDownloads(); if (!downloads.empty()) { dl->setClosing(true); // It will come back here after being removed from the queue for (const auto& p : downloads) { QueueManager::getInstance()->removeFile(p); } } else { { WLock l(cs); viewedLists.erase(aUser); } dl->close(); fire(DirectoryListingManagerListener::ListingClosed(), dl); } return true; }
void FilelistApi::on(DirectoryListingManagerListener::ListingClosed, const DirectoryListingPtr& aList) noexcept { removeSubModule(aList->getUser()->getCID()); if (!subscriptionActive("filelist_removed")) { return; } send("filelist_removed", { { "id", aList->getUser()->getCID().toBase32() } }); }
json FilelistInfo::serializeState(const DirectoryListingPtr& aList) noexcept { if (aList->getDownloadState() == DirectoryListing::STATE_DOWNLOADED) { bool loading = !aList->getCurrentLocationInfo().directory || aList->getCurrentLocationInfo().directory->getLoading(); return { { "id", loading ? "loading" : "loaded" }, { "str", loading ? "Parsing data" : "Loaded" }, }; } return Serializer::serializeDownloadState(*aList.get()); }
void DirectoryListingManager::processListAction(DirectoryListingPtr aList, const string& path, int flags) noexcept { if(flags & QueueItem::FLAG_DIRECTORY_DOWNLOAD) { DirectoryDownloadInfo::List dl; { WLock l(cs); auto dp = dlDirectories.equal_range(aList->getHintedUser().user) | map_values; if ((flags & QueueItem::FLAG_PARTIAL_LIST) && !path.empty()) { //partial list auto udp = find_if(dp, [&path](const DirectoryDownloadInfo::Ptr& ddi) { return Util::stricmp(path.c_str(), ddi->getListPath().c_str()) == 0; }); if (udp != dp.end()) { dl.push_back(*udp); } } else { //full filelist dl.assign(boost::begin(dp), boost::end(dp)); } } if (dl.empty()) return; for(auto& di: dl) { handleDownload(di, aList); } { WLock l(cs); if (flags & QueueItem::FLAG_PARTIAL_LIST) { auto dp = dlDirectories.equal_range(aList->getHintedUser().user); auto p = find(dp | map_values, dl.front()); if (p.base() != dp.second) { dlDirectories.erase(p.base()); } } else { dlDirectories.erase(aList->getHintedUser().user); } } } if(flags & QueueItem::FLAG_MATCH_QUEUE) { int matches=0, newFiles=0; BundleList bundles; QueueManager::getInstance()->matchListing(*aList, matches, newFiles, bundles); if ((flags & QueueItem::FLAG_PARTIAL_LIST) && (!SETTING(REPORT_ADDED_SOURCES) || newFiles == 0 || bundles.empty())) { return; } LogManager::getInstance()->message(aList->getNick(false) + ": " + AirUtil::formatMatchResults(matches, newFiles, bundles, (flags & QueueItem::FLAG_PARTIAL_LIST) > 0), LogMessage::SEV_INFO); } else if((flags & QueueItem::FLAG_VIEW_NFO) && (flags & QueueItem::FLAG_PARTIAL_LIST)) { aList->addViewNfoTask(path, false); } }
json FilelistInfo::serializeLocation(const DirectoryListingPtr& aListing) noexcept { const auto& location = aListing->getCurrentLocationInfo(); if (!location.directory) { return nullptr; } auto ret = Serializer::serializeItem(std::make_shared<FilelistItemInfo>(location.directory), itemHandler); ret["size"] = location.totalSize; ret["complete"] = location.directory->isComplete(); return ret; }
void DirectoryListingManager::on(QueueManagerListener::PartialListFinished, const HintedUser& aUser, const string& aXML, const string& aBase) noexcept { if (aXML.empty()) return; DirectoryListingPtr dl; { RLock l(cs); auto p = viewedLists.find(aUser.user); if (p != viewedLists.end() && p->second->getPartialList()) { dl = p->second; } else { return; } } if (dl->hasCompletedDownloads()) { dl->addHubUrlChangeTask(aUser.hint); dl->addPartialListTask(aXML, aBase, false, true, [=] { dl->setActive(); }); } else { fire(DirectoryListingManagerListener::OpenListing(), dl, aBase, aXML); } }
bool DirectoryListingManager::download(const DirectoryDownloadInfo::Ptr& di, const DirectoryListingPtr& aList, const string& aTarget, bool aHasFreeSpace) noexcept { auto getList = [&] { addDirectoryDownload(di->getListPath(), di->getBundleName(), aList->getHintedUser(), di->getTarget(), di->getTargetType(), di->getSizeUnknown(), di->getPriority(), di->getRecursiveListAttempted() ? true : false, di->getAutoSearch(), false, false); }; auto dir = aList->findDirectory(di->getListPath()); if (!dir) { // Downloading directory for an open list? But don't queue anything if it's a fresh list and the directory is missing. if (aList->getisClientView()) { getList(); } return false; } if (aList->getPartialList() && dir->findIncomplete()) { // Non-recursive partial list getList(); return false; } // Queue the directory return aList->downloadDirImpl(dir, aTarget + di->getBundleName() + PATH_SEPARATOR, aHasFreeSpace ? di->getPriority() : QueueItemBase::PAUSED_FORCE, di->getAutoSearch()); }
void DirectoryListingManager::on(QueueManagerListener::ItemFinished, const QueueItemPtr& qi, const string& dir, const HintedUser& aUser, int64_t /*aSpeed*/) noexcept { if (!qi->isSet(QueueItem::FLAG_CLIENT_VIEW) || !qi->isSet(QueueItem::FLAG_USER_LIST)) return; DirectoryListingPtr dl; { RLock l(cs); auto p = viewedLists.find(aUser.user); if (p == viewedLists.end()) { return; } dl = p->second; } if (dl) { dl->setFileName(qi->getListName()); if (dl->hasCompletedDownloads()) { dl->addFullListTask(dir); } else { fire(DirectoryListingManagerListener::OpenListing(), dl, dir, Util::emptyString); } } }
void DirectoryListingManager::handleDownload(DirectoryDownloadInfo::Ptr& di, const DirectoryListingPtr& aList) noexcept { bool directDownload = false; { RLock l(cs); auto p = finishedListings.find(di->getFinishedDirName()); if (p != finishedListings.end()) { //we have downloaded with this dirname before... di->setTargetType(TargetUtil::TARGET_PATH); di->setTarget(p->second->getTargetPath()); di->setPriority(p->second->getUsePausedPrio() ? QueueItem::PAUSED : di->getPriority()); directDownload = true; } } if (directDownload) { download(di, aList, di->getTarget(), true); return; } //we have a new directory TargetUtil::TargetInfo ti; auto dirSize = aList->getDirSize(di->getListPath()); TargetUtil::getVirtualTarget(di->getTarget(), di->getTargetType(), ti, dirSize); auto hasFreeSpace = ti.hasFreeSpace(dirSize); if (di->getSizeUnknown()) { auto queued = download(di, aList, ti.getTarget(), hasFreeSpace); if (!hasFreeSpace && queued) { LogManager::getInstance()->message(TargetUtil::formatSizeNotification(ti, dirSize), LogMessage::SEV_WARNING); } if (queued) { WLock l(cs); finishedListings.emplace(di->getFinishedDirName(), new FinishedDirectoryItem(!hasFreeSpace, ti.getTarget())); } } else { if (download(di, aList, ti.getTarget(), true)) { WLock l(cs); finishedListings.emplace(di->getFinishedDirName(), new FinishedDirectoryItem(false, ti.getTarget())); } } }
json FilelistApi::serializeList(const DirectoryListingPtr& aList) noexcept { int64_t totalSize = -1; size_t totalFiles = -1; aList->getPartialListInfo(totalSize, totalFiles); return{ { "id", aList->getUser()->getCID().toBase32() }, { "user", Serializer::serializeHintedUser(aList->getHintedUser()) }, { "state", FilelistInfo::serializeState(aList) }, { "location", FilelistInfo::serializeLocation(aList) }, { "partial", aList->getPartialList() }, { "total_files", totalFiles }, { "total_size", totalSize }, { "read", aList->isRead() }, { "share_profile", aList->getIsOwnList() ? Serializer::serializeShareProfileSimple(aList->getShareProfile()) : json() }, }; }