#1
|
|||
|
|||
Moving packages and files after completion
I'm hoping to move packages to a separate folder after completion. I know the feature does not exist in JDownload 2. I found a script at https://board.jdownloader.org/showpo...7&postcount=29 .
However, it moves all download files to a single directory, without preserving any of the original directory structure. Is there any way to fix that ? If this was C or C++, I wouldn't have any issue doing it myself, but I'm unfortunately useless with JavaScript, and ChatGPT doesn't seem sufficiently versed in EventScripter to make the change for me, despite the very clear prompt I gave it. It keeps producing code using identifiers that are not part of EventScripter. |
#2
|
|||
|
|||
Code:
/* move finished trigger : jdownloader started */ getAllFilePackages().forEach(function(package) { if (package.finished) { var curFolder = package.downloadFolder; var newFolder = curFolder.replace("\\downloading", "\\finished"); if (curFolder != newFolder) { package.downloadFolder = newFolder; } } }) Should work fine, but better run/try it on test install first. |
#3
|
|||
|
|||
Hi,
Thanks for your answer. Response below. Quote:
I tried it, as the following : Code:
/* move finished trigger : jdownloader started */ getAllFilePackages().forEach(function(package) { if (package.finished) { var curFolder = package.downloadFolder; var newFolder = curFolder.replace("d:\\Downloads\\JDownloader", "d:\\Downloads\\Complete"); if (curFolder != newFolder) { package.downloadFolder = newFolder; } } }) Thanks again. Last edited by rabidman; 10.12.2024 at 13:55. |
#4
|
|||
|
|||
Only files which were downloaded by JD into that folder (and still exist there) will be moved. Files subsequently copied or extracted to that folder will not be moved.
This is by design, since multiple packages can share a (that) common download folder and it might contain files belonging to other packages. I haver read your reply in the other thread. You can test/use this to to move the entire folder, keeping in mind it moves ALL the files/folders in it. Code:
/* demo trigger : click test run in top panel */ var myPackage = getPath("d:\\downloads\\jdownloader\\myPackage"); var complete = "d:\\downloads\\complete"; var moved = getPath(myPackage).moveTo(complete); alert(moved); If you prefer, you can also use CLI commands in eventscripter (using callSync/callAsync) to do the same. |
#5
|
||||
|
||||
Hi,
Thanks again for your response. More inline. Quote:
And why would extraction cause an issue, as long as the extraction is performed inside the package folder ? Quote:
Or alternately, perform the move only after the last package with a shared folder name has completed downloading ? Quote:
Also, what would be the correct trigger to use ? Thanks again ! Last edited by rabidman; 10.12.2024 at 10:32. |
#6
|
|||
|
|||
Quote:
Quote:
Quote:
It would not be wise to 'set' the new path while extraction is active. So, the script uses 'jdownloader started' trigger, at which point extraction presumably will have been completed. A better option is to create a "toolbar button pressed" and manually run the script by clicking the button. Point to note: "moveTo" is a filePath object method, when used to move files will sever all connection between the downloadPath and the file on disk. The link in the download list may no longer point to the correct location on disk Recommedation:
|
#7
|
|||||||
|
|||||||
Quote:
Quote:
Quote:
Quote:
I do however see a slight a problem with doing extraction after move. I would prefer the move to be atomic, so that I can subsequently safely perform manual actions on anything under Complete, such as move, delete, etc. without running the risk of having extraction accidentally fail, due to not being aware of it running in any given subfolder. It's a similar problem for the move/copy operation. My preferred way would be to extracted everything in-place in the JDownloader directory, then just move/rename the directory, which works atomically under Windows if it's on the same drive. However, I think I can work around this by checking the last modified date on any folders in the Complete directory before performing any further move/delete manually. Quote:
Quote:
Would D:\Downloads\Complete\<jd:packagename> be OK for the destination ? Quote:
The very first script in this thread was a no-op for me. Which one did you mean I should use ? Thanks |
#8
|
|||
|
|||
Quote:
Thanks. |
#9
|
||||
|
||||
@mgpai: see here for desired behaviour, https://board.jdownloader.org/showpo...22&postcount=5
__________________
JD-Dev & Server-Admin |
#10
|
|||
|
|||
|
#11
|
||||
|
||||
Correct me if I'm wrong but at least for packages with only archives && when auto extract is enabled, you could use a Packagizer rule instead of a script or alternatively just define a custom global extraction path.
__________________
JD Supporter, Plugin Dev. & Community Manager
Erste Schritte & Tutorials || JDownloader 2 Setup Download |
#12
|
|||
|
|||
Quote:
Best solution, suggested in one of the posts above. |
#13
|
||||
|
||||
Quote:
This is a huge design flaw which a lot of users have asked us to properly implement. It looks like the use case "move finished downloads to another place than the one they were initially downloaded to" is something that a lot of users want.
__________________
JD Supporter, Plugin Dev. & Community Manager
Erste Schritte & Tutorials || JDownloader 2 Setup Download |
#14
|
|||
|
|||
No to both.
|
#15
|
|||
|
|||
Script:
Code:
/* change download folder trigger : interval (set interval in ms as desired, e.g. 3600000 for 1 hour) */ getAllFilePackages().forEach(function(package) { if (package.finished && !package.archives.length) { var curFolder = package.downloadFolder var newFolder = curFolder.replace("\\jdownloader\\", "\\complete\\"); if (curFolder != newFolder) { package.downloadFolder = newFolder callAPI("downloadsV2", "removeLinks", [], [package.UUID]); } } }) Archive extractor settings: Workflow:
Please try on test install first. Last edited by mgpai; 11.12.2024 at 08:16. Reason: Updated script |
#16
|
|||
|
|||
Thank you ! This seems to be working, at least initially. I'll report if I find any issues.
|
#17
|
|||
|
|||
OK, I spoke too soon. Only two packages were moved. I believe both were archives and extracted. The vast majority of the packages are not archived, and are not getting moved.
|
#18
|
|||
|
|||
Should be working fine:
Please note, while the archives will be removed immediately, the non-archive files will be removed only when the eventscript is triggered after that, which will depend on the interval you set in the script. |
#19
|
|||
|
|||
I set the interval to 5 minutes. The non-archive files are really not getting moved.
|
#20
|
|||
|
|||
Check if the string used in replace function matches exactly to the one on disk. It is case-sensitve
Edit: The script has been updated to remove the package only if the replace was successful. Last edited by mgpai; 11.12.2024 at 08:48. |
#21
|
|||
|
|||
Hi,
Quote:
Code:
/* change download folder trigger : interval (set interval in ms as desired, e.g. 3600000 for 1 hour) */ getAllFilePackages().forEach(function(package) { if (package.finished && !package.archives.length) { var curFolder = package.downloadFolder var newFolder = curFolder.replace("D:\\Downloads\\JDownloader\\", "D:\\Downloads\\Complete\\"); if (curFolder != newFolder) { package.downloadFolder = newFolder callAPI("downloadsV2", "removeLinks", [], [package.UUID]); } } }) Unfortunately, the previously downloaded packages not containing archives are still not getting moved, even after a manual test run. |
#22
|
|||
|
|||
Quote:
Maybe @Jiaz or @psp can shed some light as to why it is working for me and not for you. |
#23
|
|||
|
|||
Quote:
Thanks. |
#24
|
|||
|
|||
Here is the downloadlist I used to test the script. Just drag 'n' drop it to the download tab.
Code:
file.io/q1pSdqTxMtJG Edit: move will fail if the file exists in the destination fodler. Last edited by mgpai; 11.12.2024 at 10:58. |
#25
|
|||
|
|||
Hi,
Quote:
Should I drag the ZIP file, or its contents ? The former results in an error : "Processing the following container failed for unknown reasons : D:\Downloads\downloadlist.zip" The later appears to have no effect. |
#26
|
|||
|
|||
Quote:
Code:
file.io/W2dGFbdzLuEP Download it to disk and dran 'n' drop to downloads tab. JD will prompt to import 7 links click yes. Alternatively, since the links are removed from ths list, the files can be moved independently, rather than set the package folder. Here too the move will fail if the file exists in the destination folder. Links will be removed from the list, only if the move is successful. Code:
/* move non-archive links trigger : interval (set as desired) */ getAllFilePackages().forEach(function(package) { if (package.finished) { package.downloadLinks.forEach(function(link) { if (!link.archive) { var curPath = link.downloadPath; var newPath = getPath(curPath.replace("\\jdownloader\\", "\\complete\\")).parent; var moved = getPath(curPath).moveTo(newPath); if (moved) { link.remove(); } } }) } }) |
#27
|
|||
|
|||
Hi,
Quote:
moved. The links for these files got removed from the Downloads list, though. Perhaps you could compare the before & after path to see if they truly got moved, rather than just checking for non-NULL string. I see that there is a _MACOSX folder in one of your packages. I'm guessing you are using Mac OS X. I'm using Windows 11. Perhaps there is some sort of platform-specific bug here. Last edited by rabidman; 11.12.2024 at 13:33. |
#28
|
|||
|
|||
Quote:
Quote:
Try a script which uses native commands: Code:
/* move non-archive links trigger : interval (set as disired) */ getAllFilePackages().forEach(function(package) { if (package.finished) { package.downloadLinks.forEach(function(link) { if (!link.archive) { var src = link.downloadPath; var dest = getPath(src.replace("\\jdownloader\\", "\\complete\\")).parent; dest.mkdirs(); callAsync(function(exitCode, stdOut, errOut) { stdOut && alert(stdOut); errOut && alert(errOut); }, "cmd", "/c", "move", "/-Y", src, dest); } }) } }) |
#29
|
|||
|
|||
Hi,
Your latest script still did not work, unfortunately. It think we were going around in circles, so I added some logging after the getPath call. Quote:
Quote:
I see above that the target directory is the wrong one. It points to the source directory, like because the src.replace call was a no-op. And it is logged with different case than it does in Windows Explorer. Explorer shows it as D:\Downloads\JDownloader . But dest is logged as D:\downloads\jdownloader . Ie. the drive letter in uppercase, but the directory names are in lowercase. That is quite strange, and I could never have guessed that's how it it worked. So, I modified the getPath call as follows : Code:
var dest = getPath(src.replace("D:\\downloads\\jdownloader\\", "D:\\Downloads\\Complete\\")).parent; I'm guessing your directory names don't have any uppercase letters, and that's why the script worked for you, but not for me. I have a few remarks here : a) link.downloadPath probably shouldn't have an upper-case drive letter, and lowercase directory names b) a case-sensitive function like replace probably isn't the right one to use for substitution on a case-insensitive file system path name A few issues remain : 1) When running the script again, it tries to move the same non-archive files again. I know this because the pop-ups continue to show up every time the script runs. This is presumably because these moved files need to be removed from the Downloads list. I can of course just remove the pop-ups, but the script should be cleaned up too. 2) For archived files, the source files do not get deleted. That's an issue with the Archive extractor rather than the script, though. It wastes disk space, and requires manual cleanup. Archives should be deleted after extraction. 3) The source directory structure does not get deleted, whether for archive or non-archive files. 4) The move and extraction process is non-atomic, with some files being moved, some extracted to the destination, and so on. I feel like : a) everything should be moved/extracted to a temporary subdirectory on the same file system as the target b) once that's complete, move that temporary subdirectory to the target directory c) delete all source archive files & paths That's more of a "want" than a "must", though. And it isn't trivial to achieve. I'm not sure if it's possible to do in a script or not. But I hope we can get there some day, still. In the meantime, the current working script will do ! Thanks again. |
#30
|
|||
|
|||
Spoke too soon. Standalone files, ie. in the multiple virtual "Various files" packages, do not get moved.
Last edited by rabidman; 12.12.2024 at 10:44. |
#31
|
|||
|
|||
b) can use regex:
Code:
var newPath = link.downloadPath.replace(/\\JDownloader\\/i,"\\complete\\"); Code:
if(moved){ link.remove(); } 2) There is a setting to delete archives after (check my screenshot above) If they are not being deleted, report here so that the devs. can look into it. 3) Code:
if (moved) { getPath(srcPath).delete(); } a) You can insert timepstamp to the save path before package name and get unique folder. b & c) When the package is finished and archive files are not present (extracted/moved/deleted) in the package, move the entire folder. (no empty folders will be left behind). |
#32
|
|||
|
|||
Quote:
Since the archive part is handled by the archive extractor, the script will have only to deal with non-archive files. Also, since you are using a pattern to save and move files, it is also possible to just move the non-archive files to the new location using a pattern. Code:
/* move finished file trigger : download stopped */ if (link.finished && !link.archive) { var src = getPath(link.downloadPath); var packageName = link.package.name; var dest = getPath("d:/downloads/complete/" + packageName); var moved = src.moveTo(dest); if (moved) { link.remove(); getPath(src.parent).delete(); } else { alert(src + " was not moved."); } } Last edited by mgpai; 12.12.2024 at 12:20. |
#33
|
|||
|
|||
Quote:
|
#34
|
|||
|
|||
If necessary, additanol alerts when move fails can be added. e.g 'src file does not exist' and 'dest file exists".
|
#35
|
|||
|
|||
Quote:
I would prefer fewer pop-ups, if possible. Ideally, comparing the files, and just deleting the source if it's identical to the destination, with an alert only if it's different, or the move fails. |
#36
|
||||
|
||||
Instead of popups you could also just write all possible alerts into one text-file.
If in the end, you got that error text-file left in your folder, you can look into it without unnerving alerts.
__________________
JD Supporter, Plugin Dev. & Community Manager
Erste Schritte & Tutorials || JDownloader 2 Setup Download |
Thread Tools | |
Display Modes | |
|
|