This question is answered.


Permlink Replies: 21 - Pages: 2 [ 1 2 | Next ] - Last Post: 22-Apr-2017 17:55 Last Post By: jGromit
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Deleting output under program control
Posted: 21-Apr-2017 23:37
 
  Click to reply to this thread Reply
I'm adding a little routine in the init.bsh of Matrix and MatrixSlide that will automatically exclude album objects that the skins can't handle anyway, like audio files and PDF's. Working just fine so far - if I find an offending object, I do a setIncluded(false), and then a quick ao.setChildren(ao.getChildren()) to get those changes to "take" in albumfiles.txt.

But there's one thing it won't do, something that the regular manual exclude does, and that's delete an output file that's already there. For example, if you have a PDF in the project, don't choose the automatic exclusion, and make the album, that PDF file lands in the output directory, as it should. But if you then choose the automatic exclusion and make the album again, the thumb and slide image for the PDF are dumped, but the original PDF is still sitting in the root of the output.

If you manually exclude an object in the Explore window, on the other hand, that copied PDF does get dumped.

I suppose I could keep track of the exclusions and do a little routine to delete the files in postdir.bsh or finally.bsh, though it's tough to keep track of the paths to them. But is there a more direct way of doing this cleanup?
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 21-Apr-2017 23:47   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
As I think about it, I could just delete these files from the output as I exclude them on the input side. These aren't newly-copied files - they're leftovers from a prior album build. So, I could take care of it within init.bsh. But how do I get the path to the correct level of the output directory?
RobM

Posts: 3,105
Registered: 4-Aug-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:00   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
Maybe you could use ao.getFile() and getMyAlbumsLocation() with a bit of string manipulation?
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:09   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
It might be even simpler than that. At the top level, I think I can get away with simply grabbing rootOutputDirectory and appending fileName. My routine is recursive, so I'd have to pass some folder information to it - at a lower level, the path would need to include the folder(s).

I think this needs more Scotch.

Edit: The real problem is that for as long as I've been coding stuff, any time I work on a recursive function, I get woozy, even dead sober.
RobM

Posts: 3,105
Registered: 4-Aug-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:13   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
Yes, recursively drink scotch and do some code until the problem is solved or you forget what you were trying to do ;)
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:16   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Perhaps I can achieve infinite regress.
RobM

Posts: 3,105
Registered: 4-Aug-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:20   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
Maybe worth looking at the code that is used in the external tool to move movies? It could be modified to find the excluded file types.
**
 * Move movie files to the slides folder
 */ 
import se.datadosen.util.*;
 
int processCount = 0;
 
void processFolder(AlbumObject folder) {
	for (AlbumObjectImpl ao : folder.getChildren()) {
		if (ao.isFolder())
			processFolder(ao);
		else {
			for (File f : outputDirectory.listFiles()) {
				String category = FileFilters.getFileCategory(f);
				if (FileFilters.MEDIA_FILE.equals(category)) {
					File slideDirectory = new File(outputDirectory, engine.getSlideDirectory());
					File destination = new File(slideDirectory, f.getName());
					IO.copyFile(f, destination, true);
					f.delete();
					processCount++;
				}
			}
		}
	}
}
 
// Execution starts here
msg =
"This script moves movies to the album's slides folder";
int option = JOptionPane.showConfirmDialog(window, msg, "Move movies to slides folder", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
if (option != JOptionPane.YES_OPTION) return;
 
processFolder(rootFolder);
 
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 00:54   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
jGromit wrote:
But if you then choose the automatic exclusion and make the album again, the thumb and slide image for the PDF are dumped....

This is actually not true. It's just that unless you include a THM file for something like a PDF, the album just picks up the generic icon. There is no thumb or slide image in the output. If you do include a THM, the thumb and slide remain unless you manually exclude the file.
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 01:14   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
I've got something that works reliably for MatrixSlide, which is the simpler case, since it doesn't support folders:
private void exUnsupp(AlbumObject ao) {
	for(AlbumObject obj : ao.getChildren()) {
		if(obj.isIncluded() && !obj.getVars().get("fileCategory").toString().equals("image") && !obj.getVars().get("fileCategory").toString().equals("video")) {
			obj.setIncluded(false);
			String[] delFiles = {obj.getVars().get("fileName"),
				obj.getVars().get("label") + engine.getPageExtension(),
				engine.getSlideDirectory() + "/" + obj.getVars().get("label") + ".jpg",
				engine.getThumbnailDirectory() + "/" + obj.getVars().get("label") + ".jpg"};
			for(String delFile : delFiles) {
				File f = new File(rootOutputDirectory + "/" + delFile);
				try {
					f.delete();
				} catch(IOException e) {}
			}
		}
		ao.setChildren(ao.getChildren());
	}
}
Then call it:
if(excludeUnsupported) exUnsupp(rootFolder);
This is in init.bsh, so a lot of the defined variables aren't available at that stage. For Matrix, I just need to incorporate the recursion, passing along the "path so far."

Edited by: jGromit, for much tighter code
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 07:47   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
Here's what I now have working for Matrix, which needs recursion to work through the tree. First define the function:
private void exUnsupp(AlbumObject ao, String path) {
	for(AlbumObject obj : ao.getChildren()) {
		if(obj.isIncluded() && obj.isFolder()) exUnsupp(obj, path + "/" + obj.getVars().get("fileName"));
		else if(obj.isIncluded() && !obj.getVars().get("fileCategory").toString().equals("image") && !obj.getVars().get("fileCategory").toString().equals("video")) {
			obj.setIncluded(false);
			String[] delFiles = {obj.getVars().get("fileName"),
				obj.getVars().get("label") + engine.getPageExtension(),
				engine.getSlideDirectory() + "/" + obj.getVars().get("label") + ".jpg",
				engine.getThumbnailDirectory() + "/" + obj.getVars().get("label") + ".jpg"};
			for(String delFile : delFiles) {
				File f = new File(path + "/" + delFile);
				try {
					f.delete();
				} catch(IOException e) {}
			}
		}
		ao.setChildren(ao.getChildren());
	}
}
Then call it:
if(excludeUnsupported) exUnsupp(rootFolder, rootOutputDirectory.toString());
The excludeUnsupported variable is from a checkbox in the skin settings.

This excludes anything that isn't an image or video, deletes the copied file from the output (in the case of things like PDF's and audio files), deletes the generated web page (like About.html), and deletes the slide and thumb images. I could be more selective about the deletions, not calling them if the files don't exist, but the try/catch takes care of that without any extra checking.

Still, a nice pre-existing method that says, "clean up the debris when I exclude an object" would be a fine thing.

Edited by: jGromit, for tighter code.
RobM

Posts: 3,105
Registered: 4-Aug-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 10:26   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
Maybe you could investigate AlbumSynchronizer(),
From the API:
void delete(AlbumObject ao)
Deletes the corresponding files in the album structure

Though it might not be intended for skin developers use.
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 13:22   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
An excellent suggestion! I had a feeling there had to be a method already defined for doing this. Much, much simpler final version:
private void exUnsupp(AlbumObject ao, String path) {
	for(AlbumObject obj : ao.getChildren()) {
		if(obj.isIncluded() && obj.isFolder()) exUnsupp(obj, path + "/" + obj.getVars().get("fileName"));
		else if(obj.isIncluded() && !obj.getVars().get("fileCategory").toString().equals("image") && !obj.getVars().get("fileCategory").toString().equals("video")) {
			obj.setIncluded(false);
			AlbumSynchronizer.delete(obj);
		}
		ao.setChildren(ao.getChildren());
	}
}
Take the weekend off. ;)

Edit: Hmmm..... This was working like a champ. Now, not. More head-scratching to come....
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 13:35   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
It gives me this error:
Cannot reach instance method: delete( se.datadosen.jalbum.AlbumObject ) from static context: se.datadosen.jalbum.AlbumSynchronizer : at Line: 216...
I wonder what that means!
RobM

Posts: 3,105
Registered: 4-Aug-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 13:43   in response to: jGromit in response to: jGromit
 
  Click to reply to this thread Reply
jGromit wrote:
It gives me this error:
Cannot reach instance method: delete( se.datadosen.jalbum.AlbumObject ) from static context: se.datadosen.jalbum.AlbumSynchronizer : at Line: 216...
I wonder what that means!
This is what happens when we don't know what we are doing ;)
I can never tell, do we call AlbumSynchronizer as you have or as AlbumSynchronizer(engine).delete(obj);
jGromit

Posts: 7,474
Registered: 31-Jan-2006
Re: Deleting output under program control
Posted: 22-Apr-2017 13:50   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
No clue. I'll tinker.

Edit: No, I'm just getting increasingly bizarre errors. Perhaps David will check in and shed some light on this one.

For the moment, it's back to my brute force method, which does work.
Legend
Forum admins
Helpful Answer
Correct Answer

Point your RSS reader here for a feed of the latest messages in all forums