This question is answered.


Permlink Replies: 17 - Pages: 2 [ 1 2 | Next ] - Last Post: 9 Jul 20, 11:27 Last Post By: RobM Threads: [ Previous | Next ]
RobM

Posts: 3,815
Registered: 4-Aug-2006
Widget code updater for multi-album projects
Posted: 11 Mar 10, 01:53
 
  Click to reply to this thread Reply
If you have an album of albums but want them all included as one album by the widget then you need to modify the injected widget code on each html page.

The attached file will perform this for you on each sub-album after all the html pages have been rebuilt. You can use the attached by putting it in the ext tools directory or in a skin directory, in which case it should be renamed to finally.bsh (or added to such a file if it already exists).

Run the code on each sub-album, not the very top level whose index page needs to keep the _jaRootPath = ".".

The actual code is shown below (note that two additional are commented out but can be put back in if used with my Notables Skin.)
If any Java coders can improve on this please do so and post the results back to this thread!

Hope it proves useful.

// Update Widget code so that it works for an Album of Albums
// _jaRootPath will be updated by making it refer back a level
// For example _jaRootPath = "."; becomes _jaRootPath = "..";
// and _jaRootPath = ".."; becomes _jaRootPath = "../..";
 
// Only run this code after all html pages have been updated!
 
// Method to process files from the current rootOutputDirectory
private processIndexPages(File dir) {
	File[] files = dir.listFiles();
	for (File f : files) {
		if ((f.isDirectory() && !(f.name.equals("thumbs")) && !(f.name.equals("res")))) {
			processIndexPages(f);	// only process sub-directories and the slides folders
		}
		// If the file is an html file then update it
		else if (f.getName().toLowerCase().endsWith(".html")) {
			replaceStringInFile(f.getParentFile(), f.getName());
		}
   	}
}
 
// Method to update the widget code
public void replaceStringInFile(File dir, String fileName){
	// initialise variables used
	String oldText ="";
	long oldTextPost = 0;
	String newText ="";
	String currentLineOfText = "";
	// start to read the current file
	try {
		File file = new File(dir, fileName);
		RandomAccessFile accessTheFile = new RandomAccessFile(file, "rw");
		// get location in the file
		// read the file line by line until eof
		while(currentLineOfText != null){
			currentLineOfText=accessTheFile.readLine();
			// eof reached, so start to update the file contents
			if(currentLineOfText==null) {
				// replace root path's that have .. with ../..
				newText = oldText.replaceFirst("_jaRootPath = \"\\.\\.","_jaRootPath = \"../..");
				// then replace rootPath . with ..
				newText = newText.replaceFirst("_jaRootPath = \"\\.\"","_jaRootPath = \"..\"");
 
				// now restore spaces and line breaks that have been removed!
				newText = newText.replaceAll("</div><script","</div> <script");
				newText = newText.replaceAll(";","; ");
				newText = newText.replaceAll("<!--_jaSkin","<!-- _jaSkin");
				newText = newText.replaceFirst("</script></body></html>","</script> \r\n</body>\r\n</html>");
 
				// access file position to overwrite old text
				accessTheFile.seek(oldTextPost);
				// update the file
				accessTheFile.writeBytes(newText);
				accessTheFile.close();
				// finished so break to avoid null point error alert
				break;
			}
			// test to see if the current line of text has the widget code
			if(currentLineOfText.indexOf("<div id="\"jalbumwidgetcontainer\"">") !=-1 && oldTextPost == 0){
				// get the position of this line
				oldTextPost = accessTheFile.getFilePointer() - currentLineOfText.length()-2;
			}
			// if at the widget code then read it and the rest of the lines of text to eof
			if (oldTextPost > 0 ) {
				oldText += currentLineOfText;
			}
		}
	} catch (Exception e) {
	JOptionPane.showMessageDialog(window, e, "Widget Code Error", JOptionPane.INFORMATION_MESSAGE);
	}
}
 
//if (resourceFolder.equals("common")) { // This line included if used with Notables Skin
	int answer = JOptionPane.showConfirmDialog(window, "Update Widget Code?", "My_Notables", JOptionPane.OK_CANCEL_OPTION);
	// User cancelled?
	if (answer != JOptionPane.OK_OPTION) return;
	processIndexPages(rootOutputDirectory);
//} // This line included if used with Notables Skin
 
 
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: Widget code updater for multi-album projects
Posted: 11 Mar 10, 09:11   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Thank you for this submission!
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 12 Mar 10, 00:19   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
This is a general question to other developers:
What I would like to do (or get done) next is to be able to update only the html pages that have changed, thus allowing the use of "Process only updated directories".

What is the easiest/best way to do this?
For example, get the current system time when "Make Jalbum" is pressed and then comparing that to each files modified date.
Or is there something already built in to Jalbum that I can use (and understand!).
TomCee

Posts: 177
Registered: 11-Jul-2005
Re: Widget code updater for multi-album projects
Posted: 12 Mar 10, 17:35   in response to: RobM in response to: RobM
Helpful
  Click to reply to this thread Reply
Hi Rob,

I've read your message, and must says that I don't have the answer. Hopefully David will jump in.

I think there's a logic in comparing the last date of the project (.jap) file to the .html file date, but haven't tried it out.

(just wanted to let you know that you're not ignored :D )

regards,
Tom
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 12 Mar 10, 21:32   in response to: TomCee in response to: TomCee
 
  Click to reply to this thread Reply
Hi Tom.
I just updated Jalbum and looked at Laza's new Turtle skin, he flags new images!
He uses
FormattedDate lastMod = new FormattedDate(se.datadosen.util.IO.deepLastModifiedFile(filename), dateFormat);


So, I hope he won't mind if I 'borrow' parts of his code to update this Widget code.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 13 Mar 10, 01:07   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
I've tried to find a method of using the 'Smart Update' ability to only modify changed html files, but not found anything that works.

The only way I can see of doing this is to (using onload.bsh) go through all the files and record the modified dates in a properties file. Then process the album as normal and using finally.bsh go through all the files again. Then test the saved dates against the current 'last modified dates' and update only those that have changed.

It would be nice, and avoid all of the coding above, if skin developers could set/update a variable that specified the widget codes _jaRootPath starting point. For example normally setting it to "." but for users making an album of albums it could be set to ".." (except of course for the true root directory for all the sub-albums). All it would need then is for a jcheckbox in the skin ui and a test for widget injection being enabled.
TomCee

Posts: 177
Registered: 11-Jul-2005
Re: Widget code updater for multi-album projects
Posted: 13 Mar 10, 01:19   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Rob,

I realy hope David steps into this. There's some deeper knowledge of the jalbum processing engine needed than I (and I think most of us) have, to solve this in a smart way.

I feel your pain :D :D

regards,
Tom
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: Widget code updater for multi-album projects
Posted: 14 Mar 10, 09:46   in response to: TomCee in response to: TomCee
 
  Click to reply to this thread Reply
I'll get back on this. As you suspect, there should be an easier way. Probably involving making sure Jalbum writes the right type of Widget code from start.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 15 Mar 10, 01:05   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
I've managed to get the code to work, but its a bit messy.
First I get the time that 'Make Jalbum' was pressed, then Icheck if it is a new build (output directory not previously made). Both of these go into the index.htt file.

In finally.bsh I then go through the root output directory and check each files modification date and compare this to the 'Make Jalbum' time, if modified after the make album time (allowing 1 second otherwise it goes wrong, some pages don't get updated and the root index page needs doing again) OR for a new build, I update the widget code. The only other code to add in this file is a test for a JCheckBox, to see if the widget code should be updated or not.

If any readers would like to test this on a dummy album I'd appreciate feedback on how well it actually works on different systems/albums. It may do until a better solution is found.

My code is now
index.htt
	<%!
		// Get the current date information (after Make Jalbum pressed)
		Date now = new Date();
		// is it a new build
		File outputAlready = new File(rootOutputDirectory + "/" + engine.getIndexPageName() + engine.getPageExtension());
		if (!outputAlready.exists())
			newBuild = true;
		else
			newBuild = false;


finally.bsh
private processIndexPages(File dir) {
	int fileUpdates = 0;
	File[] files = dir.listFiles();
	for (File f : files) {
		if ((f.isDirectory() && !(f.name.equals("thumbs")) && !(f.name.equals("res")))) {
			fileUpdates = processIndexPages(f);	// only process sub-directories and the slides folders
		}
		else if (f.getName().toLowerCase().endsWith(".html")) {
			// get the time elapsed since Make Jalbum pressed and the current file was last modified
			long elapsed_time = f.lastModified() - now.getTime() + 1000;
			// if the file has been modified or it is a new build update the widget code
			if (elapsed_time >= 0 || newBuild) {
			replaceStringInFile(f.getParentFile(), f.getName());
			fileUpdates ++;
			}
		}
   	}
	return fileUpdates;
}
 
// Change widget RootPath if common res used
// Define the Method
public void replaceStringInFile(File dir, String fileName){
	// initialise variables used
	String oldText ="";
	long oldTextPost = 0;
	String newText ="";
	String currentLineOfText = "";
	// start to read the current file
	try {
		File file = new File(dir, fileName);
		RandomAccessFile accessTheFile = new RandomAccessFile(file, "rw");
		// get location in the file
		// read the file line by line until eof
		while(currentLineOfText != null){
			currentLineOfText=accessTheFile.readLine();
			// eof reached, so start to update the file contents
			if(currentLineOfText==null) {
				// replace root path's that have .. with ../..
				newText = oldText.replaceFirst("_jaRootPath = \"\\.\\.","_jaRootPath = \"../..");
				// then replace rootPath . with ..
				newText = newText.replaceFirst("_jaRootPath = \"\\.\"","_jaRootPath = \"..\"");
 
				// now restore spaces and line breaks that have been removed!
				newText = newText.replaceAll("</div><script","</div> <script");
				newText = newText.replaceAll(";","; ");
				newText = newText.replaceAll("<!--_jaSkin","<!-- _jaSkin");
				newText = newText.replaceFirst("</script></body></html>","</script> \r\n</body>\r\n</html>");
 
				// access file position to overwrite old text
				accessTheFile.seek(oldTextPost);
				// update the file
				accessTheFile.writeBytes(newText);
				accessTheFile.close();
				// finished so break to avoid null point error alert
				break;
			}
			// test to see if the current line of text has the widget code
			if(currentLineOfText.indexOf("<div id="\"jalbumwidgetcontainer\"">") !=-1 && oldTextPost == 0){
				// get the position of this line
				oldTextPost = accessTheFile.getFilePointer() - currentLineOfText.length()-2;
			}
			// if at the widget code then read it and the rest of the lines of text to eof
			if (oldTextPost > 0 ) {
				oldText += currentLineOfText;
			}
		}
	} catch (Exception e) {
	JOptionPane.showMessageDialog(window, e, "Widget Code Error", JOptionPane.INFORMATION_MESSAGE);
	}
}
 
//include a test for a JCheckBox e.g. if (updateWidgetCode) {
	pagesProcessed = processIndexPages(rootOutputDirectory);
//}
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: Widget code updater for multi-album projects
Posted: 15 Mar 10, 11:05   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Rob, could you rephrase the purpose of this tool again. Do you use it if you have several ready-made album projects that you wish to stuff under one master album without rebuilding the whole thing? That's the only scenario where I can see one wants to add another level to rootPath?

You being able to rebuild the album(s) with a modified rootPath variable would be the ideal solution, wouldn't it?
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 15 Mar 10, 21:03   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Hi David.
In my specific case I have various 'projects' that are built individually - using different skin settings. All of these projects are part of one 'website' that I want the widget to see as one entity. If you look at my home page you will see that the site navigation is always the same on each page - linking to different 'projects' seamlessly. The user thus 'sees' one 'album' and if you look at the widget information all the pages show the same 'album visits' information.

The actual site structure is more complex, made up of the following projects/albums (each with its own .jap file):
jalbum
just_for_fun
links
links2
my_pages
photos
restored_photos

The album outputs are all contained in one wrapper directory which has one index.html page - the 'Home Page' (it actually redirects the visitor to a different page depending on the day of the week - 'Page of the day'.)

Each time I build/rebuild a project/album the widget codes that album's home page as the _jaRootPath. So I process all of the pages to make sure that the widget's -jaRootPath is set to one level further up - so, for example, the album's index page's _jaRootPath reads "..". When I originally published, the with the widget code, I pointed to the overall home directory.

Generally, if users want an album of albums with one overall 'album visits' count then they would need to do the same thing (I think!)

Does that make sense?

Edited by: RobM on 15-Mar-2010 20:04
I also use a common 'res' directory by pointing all of the album/projects outputs back up to the parent (wrapper) directory. That is I move the generated res directory back one level.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 20 Mar 10, 21:22   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Hi David.
I know you are busy but also how helpful you are, so I was wondering if you are thinking of updating the widget code?
You being able to rebuild the album(s) with a modified rootPath variable would be the ideal solution, wouldn't it?

A variable that I could modify certainly would make it very easy to produce the right widget code for album of albums. If possible, the same change on the variable resPath would help - I have to make my own version of resPath (based on rootPath with or without an extra /.. being added) as it too can be at a different level to normal.
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: Widget code updater for multi-album projects
Posted: 22 Mar 10, 12:23   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Hi Rob. Sorry for the delay on replying. I'm still thinking on what is a good way forward on this one. Perhaps it is as you suggest to simply allow you to set a prefix variable that is prepended to the rootPath. You're saying you need resPath modified too, does that mean that you wish to modify other parts of the generated code than just the widget injection code?
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: Widget code updater for multi-album projects
Posted: 22 Mar 10, 21:20   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Hi David.
I have managed to code the changes needed to have a 'res' folder at the root level, more importantly though is that the code works reliably - I'm not as confident with the _jaRootPath code being 100% reliable (I'd go for 80%!).

My general thought is that being able to make the 'root' directory at the output directory's parent level, and auto adjustment of all associated variables, would make it much easier to make an 'Album of Albums'. In terms of uploading files etc. a common resource directory saves time and space on a server.

At the moment when I update a sub-album my skin code goes through the following steps (if using a common res directory):

1. make custom variables for rootPath, slide paths and resPath. Make custom variables to offset references on slides, such as sibling links.

2. build the sub-album

3. move all the files from the output directory's 'res' directory to the common res directory.

4. update the _jaRootPath for all new/modified html pages

5. delete the empty 'res' directory from the output directory.

Being able to set variables within the skin would thus remove a lot of the work.
Looking at the number of views on this thread seems to indicate it could be something other skin developers may want too.

That said, at the moment it is only the widget code that I'm not sure I've got to work right (on different systems/album builds). Maybe it is a question worth asking of other skin developers - do they want such a function?
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: Widget code updater for multi-album projects
Posted: 25 Mar 10, 13:55   in response to: RobM in response to: RobM
Correct
  Click to reply to this thread Reply
Until I've figured out the "ultimate solution" to this, you could naturally add the widget code explicitly to the skin, with ../ prepended to the ${rootPath} reference and then instruct Jalbum to supress its own widget injection by adding autoWidgetInjection=false as a property to the skin.properties file of the skin you're using.

You could start an index.htt file with a script that updates rootPath, like this:
<% rootPath = "../" + rootPath; %>
but that won't still be respected in the widget code injection. I could change that though.
Legend
Forum admins
Helpful Answer
Correct Answer

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