-
Notifications
You must be signed in to change notification settings - Fork 155
Tags
Tags are a more flexible replacement for categories (downloads can have at most one category assigned for example)
There are a number of automatically assigned tags that denote a download's state (e.g. queued for seeding), or something directly related (active, inactive, paused).
It is possible to assign a script to be run when a download is added to a download state tag. However, note that these are non-persistent states and as such downloads will be re-assigned to tags when BiglyBT is restarted. For example, a 'complete' download will be assigned to the 'Complete' tag (and associated script run) each time BiglyBT is started.
To offer some support for existing categories within the Tag framework there is an automatically populated tag type to denote categories.
Manual tags are managed directly by the user for managing downloads. They can be created/deleted at will and downloads can be assigned to them as required. One or more downloads can be dragged to the sidebar to assign them to a tag or, if they are already tagged as such, to remove them from the tag. There are also various right-click options to manage tag assignments.
- File Locations
- Manual tags allow the specification of an initial-save location, move-on-complete, copy-on-complete, move-on-remove and move-on-assign. Note that to assign a tag to a download when adding the download you need to ensure that the 'torrent options dialog' is shown (See Tools->Options->Files: when opening a torrent, show torrent options dialog)
- Share Ratio
- Minimum share ratio - a seeding torrent won't lose its 'first-priority' status until this ratio is met
- Target share ratio - a torrent will stop seeding once this ratio is met
- Aggregate share ratio - torrents will stop seeding when the overall ratio for all torrents assigned to the tag is met
- Aggregate has priority - individual torrents will be allowed to exceed their specific ratio in order to achieve the aggregate one
- Auto-transcoding for a particular device profile
- Execute On Assign
- Allows the tag to be set to start, stop, queue, pause, resume downloads when they are assigned to the tag. There are also options to set the 'force start' attribute. A 'script' can also be set to be run on assignment, for example
javascript( "print(\"assigned!\")" )
orplugin( "azexec, Notepad.exe %D" )
andplugin( "simpleapi, "method=setnetworks&networks=I2P" )
. See 'JavaScript Constraints' below for more information on evaluation context. - This also supports 'option templates These can be used to set download options (e.g. connection limits) when a download is assigned to the Tag.
- There is also an option to post a download's magnet URI to a chat channel. This can be used to automate the publishing of downloads to other people, or other BiglyBT instances that, say, have setup an RSS feed from a chat channel and enabled auto-download to mirror downloads.
- Assign other tags to a download. This originally came from a user request to support multiple tag assignments for downloads from a Subscription. Rather than modify the Subscription to directly support more than one tag it seemed more flexible to go this route - the Subscription assigns to tag 'A' and then tag 'A' can be configured to trigger assignment to 'B', 'C'... if needed.
- Allows the tag to be set to start, stop, queue, pause, resume downloads when they are assigned to the tag. There are also options to set the 'force start' attribute. A 'script' can also be set to be run on assignment, for example
- Limits
- Controls how many downloads can be assigned to a Tag - older ones are automatically removed. How removal occurs can be specified (e.g. archive the download, move it to another tag) along with the ordering used to identify old ones for removal. Also a special limit of 999999 (yes, 6 nines) can be used to denote an actual limit of 0 (0 is already defined to mean 'unlimited') - hacktastic but there you go.
- Upload Priority
- Gives assigned downloads upload bandwidth priority over other non-upload-priority upload
- First Priority Seeding
- Forces any assigned download to be considered as a 'first-priority-seed' for seeding rule purposes.
- Notifications
- These options allow a Notification to be generated when an item is added to/removed from a Tag
- Tag Icons
- An icon can be assigned to a Tag in the Settings view - See Tag Icons for some examples.
- Tag Groups
- A Tag can be assigned to a group via right-click menu. Groups themselves support a few features:
- Exclusive - A download can only be a member of one Tag in an exclusive group at a time.
- A group can be assigned a 'move on assign' root folder. When this is done all current and future tags assigned to the group will automatically be allocated a 'move on assign' file location derived from the root location and the Tag's name.
- Each Tag Group creates two option Library view columns (one for Tag names, one for Tag icons) that will show the tags within the group that a download has assigned.
The Speed Limit Scheduler can be used to configure mappings from peer connections to Peer Set tags, via IP range, country code, network type or client id (via regular expression). Optionally this can be constrained by peers connected to downloads with specified Tags.
These tags can then be configured with upload/download limits if required to apply limits to the peers.
Additionally upload priority can be set on the tag and an 'execute on assign' action of 'Delete' can be used to disconnect any peers when they are assigned to the tag.
Properties can be applied to manual tags to automatically constrain their contents.
The 'Trackers' property allows assignment to a tag to be based on what tracker urls appear in the download's torrent. The values entered must be the FULL DNS names of the trackers required, comma separated. For example
tracker.publicbt.com, tracker.openbittorrent.com
This is a special case that denotes the tag as holding downloads that have no other tags assigned. It is possible although likely pointless to set this property on more than one tag. In the UI there are some places where you can enable the 'Untagged' tag - what this actually does is create a tag named 'Untagged' and sets this property on it.
Simple constraints allow the content of a tag to be automatically derived from assignment of other tags and download state.
Various functions can be combined with "not" (!), "and" (&&), "or" (||) and "xor" (^). Brackets can also be used to specify operator precedence.
For example, to create a tag that contains all downloads that are not tagged as "good" use
!hasTag( "good" )
For a tag that contains downloads tagged as "documentary" or "book":
hasTag( "documentary" ) || hasTag( "book" )
Defined functions:
hasTag( "<tag_name>") - does the download have tag <tag_name> assigned; does the download have peers that are a member of peer-set <tag_name> hasTagGroup( "<group_name>") - does the download have tag with a group of <group_name> assigned countTag( "<tag_name>") - returns the number of items assigned to the Tag hasNet( "<net_name>" ) - does the download have the network <net_name> enabled getTagSort( ["<tag_name_list>" [, options]] ) - get the download's Tag sort value (see setTagSort). <tag_name_list>, when supplied, is a comma separated list of tag names to be used for the result calculation. If no tag name list is supplied then the current Tag's value is used. If an empty tag name list is supplied then all Tag's values are used. Options are currently "type=<min|max|cumulative>". Default is "cumulative". getTagWeight( [options] | ["<tag_name_list>" options] ) - get the download's Tag weight. <tag_name_list>, when supplied, is a comma separated list of tag names to be used for the weight calculation. If no tag name list is supplied then all tags are used. Options are currently "type=<min|max|cumulative>". Default is "max". getTagWeight() will get the maximum weight across all Tags. isPrivate() - is a private torrent isComplete()/isChecking()/isMoving()/isStopped()/isQueued()/isPaused()/isSeeding()/isDownloading()/isRunning()/isError() - is the download complete/checking/stopped(EXCLUDES paused downloads)/queued, paused, seeding, downloading, running (not stopped, error or queued) or in error state isForceStart() - is the download force start isUnallocated() - have the files been allocated on disk yet canArchive() - can the download be archived isMagnet() - is the download a magnet download isLowNoise() - is a low noise download isGE,isGT,isLE,isLT,isEQ,isNEQ - numeric comparison functions taking 2 arguments e.g. isGE( shareratio, 0.5 ) The above can be more naturally denoted using >=, >, <=, <, ==, != e.g. shareratio >= 0.5 contains( s1, s2 [,flags] ) - does string s1 contain s2. Default is case-sensitive - supply a flag value of 1 for case-insensitive matching. The 's2' string can consist of multiple match strings separated by '|'. e.g. contains( name, "TED" ) contains( file_exts, "jpg|png" ) matches( s, regexp[, flags] ) - does string s match regular expression. Default is case-insensitive - supply a flag value of 0 for case-sensitive matching e.g. matches( name, "^[a-f]" ) - download name starts with a, b, c, d, e or f See https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for more details hoursToSeconds/htos/h2s( numeric) - convert hours to seconds daysToSeconds/dtos/d2s( numeric) - convert days to seconds weeksToSeconds/wtos/w2s( numeric) - convert weeks to seconds getConfig( c ) can be used to access configuration variables. Currently the following are supported: queue.seeding.ignore.share.ratio - Queue->Seeding->Ignore Rules: Ignore torrents that have a share ratio of ... hasTagAge( "<tag_name>" ) - seconds download has been assigned to tag for. IS reset on removal from tag (c.f. tag_age) length( string ) - length of the string, -1 if null lowercase( string ) - convert a string to lower case isIpFiltered() - is the download's IP filter active? isNew() - is the download new (completed and not opened)? isSequential() - has the download been marked as sequential (overall ascending, not at the file/block level) isShare() - is the download a share? See MyShares for details isSuperSeeding() - is the download super-seeding? setColors( foreground [,background] [,priority]) - Set downloads assigned to the Tag's row colors in Library views: colors are specified as #rrggbb or 0xrrggbb with rr, bb, gg in base 16. e.g. #ffffff = white, #ff0000 - red Use -1 for a color if you don't want to set it priority is used to resolve issues when more than one color applies to a row - the highest priority on will be selected. If you want a tag you can manually add/remove downloads from then set its constraint to the setColors you desire and then set its scope to 'removal only' NOTE 1. For the colors to be shown you MUST enable the 'Tag Colors' column in the Library view. NOTE 2. This sets the color for the Tag, NOT the downloads. Don't try and be smart and use multiple setColors in an expression, IT WON'T WORK. setTagSort( numeric [,options]) - set the numeric tag sort value for this Tag. Options are currently limited to "reverse" meaning reverse sort and "random" (in which case a shortened form setTagSort( "random" ) can be used as the numeric value is irrelevant). The Tag Sort can be applied to download library positions, either manually or periodically - see the Tag settings panel. tagPosition( "<tag_name>" [,sort] ) - position of the download in the named tag, starting from 0 and ordered by the download 'order'. -1 if the download isn't a member of the tag. The optional sort parameter can be set to 2 to cause downloads to be ordered by the time added to tag. timeToElapsed( time ) - convert a time value into elapsed seconds since the present. toMB( numeric ) - convert a number to MB (1000*1000). toMiB( numeric ) - convert a number to MiB (1024*1024) toGB( numeric ) - convert a number to GB (1000*1000*1000). toGiB( numeric ) - convert a number to GiB (1024*1024*1024). countTrackers() - number of trackers defined for the download (0 for decentralised torrents) plus( numeric, numeric ) - add two numbers. minus( numeric, numeric ) - subtract two numbers. mult( numeric, numeric ) - multiply two numbers. div( numeric, numeric ) - divide two numbers. rem( numeric, numeric ) - remainder of dividing two numbers. The above can more naturally be denoted via +, -, *, / and % min( numeric, numeric ) - minimum of two numbers. max( numeric, numeric ) - maximum of two numbers. ifThenElse( boolean, expr, expr ) - implements the usual semantics of if-then-else. The above can also be expressed using the "a?b:c" notation. trackerPeers( source ) - peers reported by the source ( current only DHT sources are supported - "BiglyBTDHT","mlDHT", "I2PDHT" ). trackerSeeds( source ) - seeds reported by the source (as above) pluginOption( plugin_id, attribute_name ) - supports attribute (boolean) "enableannounce" for plugin ids "dht", "mldht" or "i2p".
Defined constants:
max32 - numeric, maximum 32-bit integer min32 - numeric, minimum 32-bit integer max64 - numeric, maximum 64-bit integer min64 - numeric, minimum 64-bit integer
Defined variables:
Note - Suffixes can be added to numeric constants for file sizes - MB, Mib etc. share_ratio: float - download's share ratio (Integer.MAX_VALUE or ∞ if no download) target_ratio: float - download's target share ratio (download specific value if set, default otherwise) name: string - download's name age: numeric - seconds since download was added percent: float - percentage completed true: boolean - only use for this is when used alone to create a tag with all downloads seeding_for: numeric - seconds download has been seeding for downloading_for: numeric - seconds download has been downloading for last_active/last_xfer: numeric - seconds since the download last uploaded or downloaded data (note this differs from the "last active" library column - this is actually "last queued") last_queued: numeric - seconds since the download was last queued (Since 3601) swarm_merge_bytes: numeric - number of bytes swarm merged resume_in: numeric - number of seconds until a pause-for... download is resumed min_of_hour: numeric - minute of the hour: 0 -> 59 hour_of_day: numeric - hour of the day: 0 -> 23 day_of_week: numeric - day of the week: 1=Sunday, 2=Monday etc. seed_count: numeric - number of seeds peer_count: numeric - number of peers seed_peer_ratio: float - ratio of seeds to peers (Integer.MAX_VALUE or ∞ if no peers) tag_age: numeric - seconds since download was assigned to the tag (NOT reset on removal from the tag) completed_age: numeric - seconds since download completed peer_max_completion: float - maximum completion of connected peers leech_max_completion : float - maximum completion of connected leechers (i.e. seeds are ignored) peer_average_completion: float - average completion of connected peers and ourselves size, size_mb, size_gb: numeric - size of torrent file in bytes/MiB/GiB (binary - use suffixes for more control) file_count: numeric - number of files in the download file_count_selected: numeric - number of files selected for download file_names: String[] - file names in torrent - for use with 'matches' and 'contains' functions availability: float - availability of the download up_idle: numeric - seconds since data last uploaded (Long.MAX_VALUE if never uploaded) down_idle: numeric - seconds since data last downloaded (Long.MAX_VALUE if never downloaded) downloaded: numeric - number of verified data bytes downloaded uploaded: numeric - number of data bytes uploaded remaining: numeric - number of bytes remaining to be downloaded save_path: String - download's save location save_folder: String - parent folder of save_path max_up : numeric - download's maximum upload limit. -1: disabled, 0: unlimited, >0: speed in bytes-per-second max_down: numeric - download's maximum download limit - see max_up for details. file_names_selected: String[] - file names in torrent selected for download - for use with 'matches' and 'contains' functions file_exts: String[] - file name extensions in torrent - for use with 'matches' and 'contains' functions file_exts_selected: String[] - file name extensions in torrent selected for download - for use with 'matches' and 'contains' functions torrent_type: numeric - 1=v1; 2=hybrid; 3=v2 file_paths: String[] - absolute paths of files in torrent file_paths_selected: String[] - absolute paths of files in torrent selected for download tag_names: String[] - download's assigned tags - for use with 'matches' and 'contains' functions tracker_status: String - overall tracker status full_copy_seen: time - time at which a full copy was last seen (i.e. a seed was connected to). <0: never; current time: last know status was good; prior time: the time at which the download transitioned from having a connected seeds to not having a connected seed. Note that this is generally NOT useful for completed downloads as connections to seeds will normally not occur. down_speed: numeric - download speed in bytes-per-second, average over last minute. up_speed: numeric - uploadspeed in bytes-per-second, average over last minute. session_age: numeric - seconds since the torrent was most recently started in the current session. my_rating: numeric - personal rating value as assigned in the Rating & Comments plugin column. moc_path: string - effective "move on complete" path, "" if none. trackers: String[] - tracker names (host+[":"port]) in the torrent for use with 'matches' and 'contains' functions. position: numeric - download index/position in the library. Complete and Incomplete are numbered separately from 1. Since 3601_B27.
Comments can be included in the constraints. Whole line comments can be prefixed by #, // can be used for trailing comments and /* ... */ for arbitrary embedded comments. For example
# test this and that peer_count > 20 || // or the other seed_count /* hmmmm */ < 30
This requires Java the installation of the 'JavaScript Provider' plugin - see http://plugins.biglybt.com/details/azjscripter.
To invoke JavaScript use the constraint function 'javascript' and supply the script to be executed as a string. For example:
javascript( "download.getTorrent().getSize() > 100*1024*1024" )
The script should return a boolean indicating whether or not the download should be assigned to the tag or not.
The script can call existing functions defined within the JavaScript Provider plugin 'general script' area or loaded from other .js files if required.
See JavaScript Tag Constraints for more information.
The scope of a constraint can be set. By default the constraint is applied to determine whether or not a download should be added to or removed from the tag. The scope feature allows you to specify whether only half of this process should be applied - either only to determine if a download is to be added (with manual removal) or vice-versa (manual addition, automatic removal). If you manually remove a download from a tag that has a scope of add-only or add+remove then it will be re-added to it. Note however that you can manually remove a download from a remove-only tag while the constraint is true (as it won't be automatically re-added)
Consider a tag, say 'priority_downloads', that has no rate limits - you manually assign downloads as you see fit. Once the download is complete though it would be nice if they automatically removed themselves from it. This can be achieved by setting the tag with a constraint of "!isComplete()" and a scope of 'removal only'
A further scope of 'new downloads' is also available. Selecting this will cause the constraint to be evaluated when a new download is added but not at any other time. This is useful for setting up a download's initial tag assignments that can manually be changed later.
A manual tag can have one or more tracker templates (see Tracker Templates and Lists ) and operations applied to it so that when a download is assigned to the tag trackers are set/merged/removed
- Add Trackers
- You can automatically add a set of trackers to downloads that are assigned to a Tag as follows.
- Create the Tag to perform this function (call it 'AddedTrackers' say)
- Right-click on the AddedTrackers Tag and select 'Tracker Templates->New...' to create a new tracker template. Enter a name (say 'Added'), hit the 'edit as text' button and paste in your new tracker announce URLs, one per line with a blank line between each entry). Save the template
- Now assign that template with a 'merge' action by right-clicking on AddedTrackers Tag again, selecting 'Tracker Templates->Added->Merge'
- If you wanted to automatically do this for all torrents then set the constraint for the 'AddedTrackers' Tag to 'true' to ensure that all torrents are assigned to it
- Remove Dead Trackers
- You can automatically remove a set of dead trackers from torrents that are assigned to a Tag as follows.
- Create the Tag to perform this function (call it 'DeadTrackers' say)
- Right-click on the DeadTrackers Tag and select 'Tracker Templates->New...' to create a new tracker template. Enter a name (say 'Dead'), hit the 'edit as text' button and paste in your dead tracker announce URLs, one per line with a blank line between each entry). Save the template
- Now assign that template with a 'remove' action by right-clicking on DeadTrackers Tag again, selecting 'Tracker Templates->Dead->Remove'
- If you wanted to automatically do this for all torrents then set the constraint for the 'DeadTrackers' Tag to 'true' to ensure that all torrents are assigned to it
You can have an RSS feed automatically generated from a tag's contents by doing the following:
- Enable local RSS feeds via Tools->Options->Local RSS etc. Review the various parameters there to control access to these local feeds. You can click on the link at the top of the options panel to view a (very simple) webpage that links to the various RSS feeds you have enabled
- Right-click on a tag and select 'Create Local RSS Feed' to generate a feed for that tag
Tag-based RSS feeds are useful if you want to share a set of downloads with others. If you make the feeds public, for example, others can add the feed to their client to access the downloads. Alternatively you can use the RSS To Chat plugin to automatically post details of downloads assigned to a tag to a chat channel of your choice (optionally anonymous) for other users to see.
For manual Tags there is a right-click option in the Sidebar/Tags Overview that allows you to specify that the Tag's downloads automatically have download links posted to a Chat channel. This gives the ability to share the downloads with other users that open the Chat channel in their client. Download details are gradually posted to the channel and, as the channel has a limit to the number of messages it can hold, the downloads will be cycled through to ensure that all downloads are posted.
The best way for a client to use the channel is for them to create an RSS Feed from it - in the chat there is an RSS icon to the right of the message entry box to do this. The RSS feed will then accumulate messages from the channel over time and can be searched for downloads easily.
As a publisher you may also want to associate your downloads with a Subscription to help others discover your channel. To do this do the same thing as a client and create an RSS channel via the icon in the Chat interface and make sure you change the name to something unique to your Tag's contents. Now locate the RSS Feed (Subscription) that has been created and right-click on it to select 'auto-download new results'. Then via the same menu select 'Reset to initial state'. This will associate the subscription with the Tag's downloads and other users will see that subscription if they happen to download something that is in your Tag.
Check the UI options under Tools->Options->Interface->Tags for general settings.
Tags can be displayed in the sidebar in the same way that categories can. Right-click on the 'My Torrents' sidebar entry to show a menu that has options controlling visibility.
In a similar vein, tag buttons can be enabled in Library views to filter on tag - right-click on the Library view header area for a menu.
By default the visibility of Tags in the sidebar also controls whether or not individual Tags are shown as Library filter buttons (the classic UI ignores this and shows them all). A separate Tag setting 'Is Filter' is available to explicitly indicate which Tags should be considered as acting as filters. For backwards compatibility a general option has also been added to enable this behaviour.
To see all the details of all your Tag use the 'Tags Overview' view - look at the main 'View' menu in the client to show this.
By default the order of the tags in the sidebar, and tag button order in Library views, is alphanumeric. This can be further refined by using 'groups' to group sets of tags into similar sets. Groups are sorted first and then the tags within them. The use of a numeric prefix can be used with groups if desired to force a particular order.
The Tag Discoveries view allows you to see tags that other people have publicly assigned to the torrents you have. Use View->Tag Discoveries to show the view, and click the Scan button to start the tag lookup.
This allows initial tags to automatically be assigned to downloads when added. The configuration settings for this are under Tools->Options->Files and can also be reached via the right-click menu in the files area of the 'add torrent options' dialog.
Tags are selected based on file extension matching, with an optional tag assignment if no extensions match. An additional option allows assignment of the 'best' matching tag rather than all matching tags. 'Best' is defined as the largest cumulative matching file size for an extension.
Create a Tag and set its 'execute on assign' to 'Stop'
Set the Tag's constraint to auto-assign downloads after they have been seeding for a time with
isGE( seedingfor, <time_in_seconds>)
Normally when a download reaches its share ratio limit it will enter a 'Queued' state - inactive but ready to restart seeding should some other criteria requires it to start (e.g. the download has no seeds)
If you want to actually stop seeds that reach their share ratio then
- Create a Tag and set its 'execute on assign' to 'Stop'
- Set the Tag's constraint to auto-assign downloads after they have reached their share ratio with
isComplete() && share_ratio >= target_ratio
Set up a Tag with a constraint that causes downloads to be assigned to it when they meet the required share ratio (e.g. 1.0)
isGE( shareratio, 1.0 )
Go to the Tag settings and enable the 'Post message to notifications: on addition' option.
Configure notifications to play an alert via Tools->Options->Interface->Alerts: Play a sound when notification added
The following constraint selects downloads that haven't been active in the last 30 days. Note that it also excludes downloads that have never been active by checking against a large upper bound (around 100 years in this case) as such downloads have a 'last_active' of Long.MAX_VALUE.
isGT( last_active, 2592000 ) && isLT( last_active, 3153600000 )
When an archived file is restored it is automatically assigned to the 'Restored' tag. In order to automatically re-archive files after a number T of seconds you can achieve this by doing the following:
1) create a tag, 'Restored_Recently' (say) and set its constraint to be
hasTag( "Restored" ) && isLT( tag_age, T )
2) create a tag, 'Restored_Temp' (say) and set its constraint to be
hasTag( "Restored_Recently" )
This intermediate tag is required to ensure that a restored download has been added to 'Restored_Recently' before it is considered for re-archive.
3) create another tag, 'Restored_Old' (say) and set its constraint to be
hasTag( "Restored_Temp") && !hasTag( "Restored_Recently" )
Also set its 'execute on assign' action to 'Stop' and configure its 'limits' to have a count of 999999 (see above, hack to denote 0) and removal policy of 'Archive'
Use 'Tracker Properties' to automatically assign the desired downloads to a Tag. Then also set that Tag's 'Execute On Assign' value via right-clicking on it - select the 'Apply Options Template' item and then configure the settings as desired.
Decentralized chat channels can be used to communicate with other users and are used in this example. Say you want to automatically post a magnet link for a download to chat channel 'CoolStuff' when a download is assigned to Tag 'Cool':
- Create the Tag 'Cool' and enable the 'save messages across restart' option
- Enable 'Local RSS etc.' in Tools->Options->Local RSS etc. and configure as required
- Right-click on the 'Cool' Tag in the sidebar and enable 'Create local RSS feed'
- Go back to Tools->Options->Local RSS etc. and click the 'Click to view the local home page' link at the top
- When the browser opens navigate to the 'Cool' Tag RSS link (something like http://127.0.0.1:6905/tags/3-nnn) - this will show an RSS feed generated from the Tag's contents
- Add the RSS URL as a new Subscription in BiglyBT via the sidebar Subscriptions entry
- Install the 'RSSToChat' plugin and configure it to post messages from the Subscription to the 'CoolStuff' chat
- Job done!
You can use the following constraint expression to change the foreground text colour in the Library views for downloads that contain either .zip or .jar files:
matches( file_names_selected, "(\.zip|\.jar)$") && setColors( #00a0a0 )
See the description of setColors for details on how to change background color and prioritize things.
Tag groups support an option to automatically set the 'move-on-assign' location of member Tags based on a root folder and the tag name. For example, if you set the root folder to C:\Downloads\ and the group has a tag named 'Fred' then any downloads assigned to Fred will have their data stored in C:\Downloads\Fred. Creating a Tag named 'Bill' and assigning it to the group will result in Bill's downloads being stored in C:\Downloads\Bill.
Create a tag, e.g."LastToDownload"
Create a second tag with a constraint of
!isComplete() && setTagSort( hasTag( "LastToDownload" )?1:0)
You can either manually apply via the button in the second tag's settings or configure it there to be periodically applied automatically.
bigly help