Bundles

Ideas for ADC may be presented here for others to review and point out flaws or further improve the idea.
Forum rules
If you have an account on the wiki, remember to update the ADC Proposals page for new ideas.

http://dcbase.org/wiki/ADC_Proposals_list
Locked
Pretorian
Site Admin
Posts: 214
Joined: 21 Jul 2009, 10:21

Bundles

Post by Pretorian » 05 Aug 2014, 11:37

I don't know if AirDC++ has this partially or completely implemented, but I figured it would be good to have some of it specified here. I'll just post everything I've got stored, so this isn't a proper proposal. It would be good if someone who built the extension can chime in...

Description (straight up from AirDC++):
Bundles


What is a bundle?

Bundle is an upper level grouping for the files that are being download, which can consist of multiple files. In 2.30, all downloaded files, except file list and text files viewed in the client, will be part of a bundle. The grouping isn?t fixed, and the bundle content can be modified in several ways. There are two types of bundles: directory bundles and file bundles.


Directory Bundle

If you have chosen to download a folder (or many of them) from a file list/search/auto search, each of the selected parent folders will become a bundle that will contain all files that are inside the particular folder(s). A common example of a directory bundle is a ?release? folder that is being downloaded from a file list/search/auto search.

Directory bundles can be moved to a different location, possible sub folders can be moved separately when they will split into new bundles. If you are trying to move or download a bundle to a location with an existing directory bundle, the bundle being moved/created will always be merged into the existing one.

The bundle files will be grouped together in transfer view, with the parent item showing the progress and other information of the whole bundle.

When moving/removing bundles, the user will be asked whether he also wants to move/rename possible finished files that are part of the bundle (or the particular sub folder). Individual files can also be added and removed from the bundle.


File Bundle

File bundles will be created when you try to download individual files from the search or from a file list, as in those cases there is no folder that can be used to unite the files. Basically file bundle only are single files, but the client threats them equal to directory bundles (for example when searching for alternates or when determining the download order).

There can also be several file bundles within the same directory. However, there can't be file bundles inside a directory bundle. If you try to download a directory into a folder containing file bundles, the file bundles will be always merged into the directory bundle. Furthermore, file bundles are only created if there is no directory bundle in the target destination folder, in which case the file would be added into the existing directory bundle.

You can also split individual files from directory bundles by moving them to a different location, and then the split items will become file bundles (or being merged into another directory bundle if there is one).
ADC Commands:
PDB command

Fields:
HI = Hub IP (and port?)
BU = Remote Bundle
TH = TTH
UP = New notification or update
AD = Add hash set list ("TTHlist")
RE = Require reply
NO = Notify only, don't download hash set ("TTHlist")
RM = Remove notifications for a selected user and bundle

UDB command

Fields:
AD = Add/Create bundle
CH = Change bundle
UD = Update bundle
FI = Finish bundle
RM = Remove bundle
UDB code:

Code: Select all

if (cmd.hasFlag("AD", 1)) {
		//LogManager::getInstance()->message("ADD UPLOAD BUNDLE");
		createBundle(cmd);
	} else if (cmd.hasFlag("CH", 1)) {
		//LogManager::getInstance()->message("CHANGE UPLOAD BUNDLE");
		changeBundle(cmd);
	} else if (cmd.hasFlag("UD", 1)) {
		//LogManager::getInstance()->message("UPDATE UPLOAD BUNDLE");
		updateBundleInfo(cmd);
	} else if (cmd.hasFlag("FI", 1)) {
		//LogManager::getInstance()->message("FINISH UPLOAD BUNDLE");
		finishBundle(cmd);
	} else if (cmd.hasFlag("RM", 1)) {
		//LogManager::getInstance()->message("REMOVE UPLOAD BUNDLE");
		removeBundleConnection(cmd);
	} else {
		//LogManager::getInstance()->message("NO FLAG");
	}
PDB code

Code: Select all

void SearchManager::onPBD(const AdcCommand& cmd, UserPtr from) {
	string remoteBundle;
	string hubIpPort;
	string tth;
	bool add=false, update=false, reply=false, notify = false, remove = false;

	for(auto i = cmd.getParameters().begin(); i != cmd.getParameters().end(); ++i) {
		const string& str = *i;
		if(str.compare(0, 2, "HI") == 0) {
			hubIpPort = str.substr(2);
		} else if(str.compare(0, 2, "BU") == 0) {
			remoteBundle = str.substr(2);
		} else if(str.compare(0, 2, "TH") == 0) {
			tth = str.substr(2);
		} else if(str.compare(0, 2, "UP") == 0) { //new notification of a finished TTH
			update=true;
		} else if (str.compare(0, 2, "AD") == 0) { //add TTHList
			add=true;
		} else if (str.compare(0, 2, "RE") == 0) { //require reply
			reply=true;
		} else if (str.compare(0, 2, "NO") == 0) { //notify only, don't download TTHList
			notify=true;
		} else if (str.compare(0, 2, "RM") == 0) { //remove notifications for a selected user and bundle
			remove=true;
		} else {
			//LogManager::getInstance()->message("ONPBD UNKNOWN PARAM: " + str);
		}
	}

	if (remove && !remoteBundle.empty()) {
		//LogManager::getInstance()->message("ONPBD REMOVE");
		QueueManager::getInstance()->removeBundleNotify(from, remoteBundle);
	}

	if (tth.empty()) {
		//LogManager::getInstance()->message("ONPBD EMPTY TTH");
		return;
	}

	string url = ClientManager::getInstance()->findHub(hubIpPort);

	if (update) {
		//LogManager::getInstance()->message("PBD UPDATE TTH");
		QueueManager::getInstance()->updatePBD(HintedUser(from, url), TTHValue(tth));
		return;
	} else if (remoteBundle.empty()) {
		//LogManager::getInstance()->message("ONPBD EMPTY BUNDLE");
		return;
	}

	HintedUser u = HintedUser(from, url);
	if (notify) {
		//LogManager::getInstance()->message("PBD NOTIFY");
		QueueManager::getInstance()->addFinishedNotify(u, TTHValue(tth), remoteBundle);
	} else if (reply) {
		//LogManager::getInstance()->message("PBD REQUIRE REPLY");

		string localBundle;
		bool notify = false, add = false;
		if (QueueManager::getInstance()->checkPBDReply(u, TTHValue(tth), localBundle, notify, add, remoteBundle)) {
			//LogManager::getInstance()->message("PBD REPLY: ACCEPTED");
			AdcCommand cmd = toPBD(hubIpPort, localBundle, tth, false, add, notify);
			ClientManager::getInstance()->send(cmd, from->getCID(), false, true);
		} else {
			//LogManager::getInstance()->message("PBD REPLY: QUEUEMANAGER FAIL");
		}
	}

	if (add) {
		try {
			QueueManager::getInstance()->addBundleTTHList(u, remoteBundle, TTHValue(tth));
		}catch(const Exception&) { }
	}
}

Locked