Beispiel #1
0
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()));
		}
	}
}
Beispiel #13
0
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() },
    };
}