Various updates

This commit is contained in:
Norberto Lopez
2013-04-09 02:59:45 +00:00
parent ab6a50e29c
commit 39ff324eb5
6 changed files with 275 additions and 111 deletions

View File

@@ -8,11 +8,11 @@ import shutil
import signal
import subprocess
import sys
import time
def getDistInfo(distPath):
appName = None
version = None
buildDate = None
cfgFile = os.path.join(distPath, 'delta', 'app.cfg')
if os.path.isfile(cfgFile) == False:
@@ -20,32 +20,27 @@ def getDistInfo(distPath):
print('Release will not be deployed...')
exit()
isNameMode = isVerMode = False
exeMode = None
f = open(cfgFile, 'r')
for line in f:
line = line[:-1]
if line == '-name':
isNameMode = True
isVerMode = False
elif line == '-version':
isNameMode = False
isVerMode = True
elif line.startswith('-') == True:
isNameMode = False
isVerMode = False
elif isNameMode == True and len(line) > 0:
if line.startswith('-') == True:
exeMode = line;
elif exeMode == '-name' and len(line) > 0:
appName = line
elif isVerMode == True and len(line) > 0:
elif exeMode == '-version' and len(line) > 0:
version = line
elif exeMode == '-buildDate' and len(line) > 0:
buildDate = line
f.close()
if appName == None or version == None:
if appName == None or version == None or buildDate == None:
print('Distribution corresponding to the folder: ' + distPath + ' does not appear to be valid!')
print('The configuration file, ' + cfgFile+ ', is not valid.')
print('Release will not be made for app ' + appName)
exit()
return (appName, version)
return (appName, version, buildDate)
def handleSignal(signal, frame):
@@ -54,39 +49,40 @@ def handleSignal(signal, frame):
sys.exit(0)
def updateAppConfig(versionPath, deployDate):
cfgFile = os.path.join(versionPath, 'delta', 'app.cfg')
# Updated the config file
f = open(cfgFile, 'a')
f.write('-deployDate\n')
f.write(str(deployDate) + '\n')
f.close()
def updateReleaseInfo(installPath, appName, version, deployDate):
def updateReleaseInfo(installPath, appName, version, buildDate):
verFile = os.path.join(installPath, 'releaseInfo.txt')
releaseInfo = []
# Read the file
if os.path.isfile(verFile) == True:
f = open(verFile, 'r')
for line in f:
tokens = line[:-1].split(',', 1);
if len(tokens) == 2 and tokens[0] != 'name':
releaseInfo.append((tokens[0], tokens[1]))
# Create the release info file
if os.path.isfile(verFile) == False:
f = open(verFile, 'w')
f.write('name' + ',' + appName + '\n')
f.close()
# Add the new version
releaseInfo.append((version, deployDate))
# Write the updated file
f = open(verFile, 'w')
f.write('name' + ',' + appName + '\n')
for verTup in releaseInfo:
f.write(verTup[0] + ',' + verTup[1] + '\n')
# Updated the release info file
f = open(verFile, 'a')
f.write(version + ',' + buildDate + '\n')
f.close()
# # Read the file
# if os.path.isfile(verFile) == True:
# f = open(verFile, 'r')
# for line in f:
# tokens = line[:-1].split(',', 1);
# if len(tokens) == 2 and tokens[0] != 'name':
# releaseInfo.append((tokens[0], tokens[1]))
# f.close()
# # Add the new version
# releaseInfo.append((version, buildDate))
# # Write the updated file
# f = open(verFile, 'w')
# f.write('name' + ',' + appName + '\n')
# for verTup in releaseInfo:
# f.write(verTup[0] + ',' + verTup[1] + '\n')
# f.close()
if __name__ == "__main__":
@@ -125,8 +121,8 @@ if __name__ == "__main__":
print('Release will not be deployed...')
exit()
# Determine the appName and version of the distribution
(appName, version) = getDistInfo(distPath)
# Determine the appName, version, and buildDate of the distribution
(appName, version, buildDate) = getDistInfo(distPath)
# Check to see if the deployed location already exists
installPath = os.path.join(rootPath, appName)
@@ -151,13 +147,5 @@ if __name__ == "__main__":
# Copy over the contents of the release folder to the deploy location
shutil.copytree(distPath, versionPath, symlinks=True)
# Compute the official deployDate
exeDate = time.localtime()
deployDate = time.strftime('%Y%b%d %H:%M:%S', exeDate)
# Update the app.cfg file
updateAppConfig(versionPath, deployDate)
# Update the version info
updateReleaseInfo(installPath, appName, version, deployDate)
updateReleaseInfo(installPath, appName, version, buildDate)

View File

@@ -1,6 +1,7 @@
#! /usr/bin/env python
import sys
import os
import time
import sys
def handleSignal(signal, frame):
"""Signal handler, typically used to capture ctrl-c."""
@@ -86,6 +87,13 @@ def buildAppLauncherConfig(destFile, args):
f.write(args.version + '\n')
f.write('\n')
# Build date section
exeDate = time.localtime()
buildDate = time.strftime('%Y%b%d %H:%M:%S', exeDate)
f.write('-buildDate\n')
f.write(buildDate + '\n')
f.write('\n')
# MainClass section
f.write('-mainClass\n')
f.write(args.mainClass + '\n')

View File

@@ -1,5 +1,6 @@
package distMaker;
import glum.gui.panel.generic.MessagePanel;
import glum.gui.panel.task.FullTaskPanel;
import glum.io.IoUtil;
import glum.net.Credential;
@@ -13,6 +14,7 @@ import java.net.URL;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import distMaker.gui.PickReleasePanel;
@@ -25,13 +27,18 @@ public class DistMakerEngine
// Gui vars
private JFrame parentFrame;
private MessagePanel msgPanel;
private PickReleasePanel pickVersionPanel;
public DistMakerEngine(JFrame aParentFrame, URL aUpdateUrl)
{
updateUrl = aUpdateUrl;
currRelease = null;
refCredential = null;
parentFrame = aParentFrame;
msgPanel = new MessagePanel(parentFrame);
msgPanel.setSize(375, 180);
initialize();
}
@@ -42,10 +49,29 @@ public class DistMakerEngine
public void checkForUpdates()
{
FullTaskPanel taskPanel;
File installPath;
String appName;
// Bail if we do not have a valid release
if (currRelease == null)
{
if (DistUtils.isDevelopersRelease(getClass()) == true)
displayErrorDialog("Updates are not possible in a developer environment.");
else
displayErrorDialog(null);
return;
}
appName = currRelease.getName();
// Determine the destination where to drop the release
installPath = DistUtils.getAppPath().getParentFile();
if (installPath.setWritable(true) == false)
{
displayErrorDialog("The install path, " + installPath + ", is not writable. Please run as the proper user");
return;
}
// Setup our TaskPanel
taskPanel = new FullTaskPanel(parentFrame, true, false);
taskPanel.setTitle(appName + ": Checking for updates...");
@@ -61,6 +87,16 @@ public class DistMakerEngine
*/
public void markSystemFullyStarted()
{
String msg;
// Notify the user, if the application has been successfully updated
if (System.getProperty("distMaker.isUpdated") != null)
{
msg = "The application, " + currRelease.getName() + ", has been updated to ";
msg += "version: " + currRelease.getVersion();
displayErrorDialog(msg);
}
// TODO: Flush this out
}
@@ -86,13 +122,13 @@ public class DistMakerEngine
BufferedReader br;
DateUnit dateUnit;
String currInstr, strLine;
String appName, verName, deployStr;
long deployTime;
String appName, verName, buildStr;
long buildTime;
currRelease = null;
appName = null;
verName = null;
deployStr = null;
buildStr = null;
// Locate the official DistMaker configuration file associated with this release
appPath = DistUtils.getAppPath();
@@ -100,7 +136,13 @@ public class DistMakerEngine
// Bail if there is no configuration file
if (cfgFile.isFile() == false)
{
// Alert the user to the incongruence if this is not a developer's build
if (DistUtils.isDevelopersRelease(getClass()) == false)
displayErrorDialog(null);
return;
}
// Read in the configuration file
br = null;
@@ -129,8 +171,8 @@ public class DistMakerEngine
appName = strLine;
else if (currInstr.equals("-version") == true)
verName = strLine;
else if (currInstr.equals("-deployDate") == true)
deployStr = strLine;
else if (currInstr.equals("-buildDate") == true)
buildStr = strLine;
}
}
@@ -143,16 +185,21 @@ public class DistMakerEngine
IoUtil.forceClose(br);
}
if (appName == null || verName == null || deployStr == null)
if (appName == null || verName == null)
{
displayErrorDialog(null);
System.out.println("Failed to properly parse DistMaker config file: " + cfgFile);
return;
}
// Form the installed Release
dateUnit = new DateUnit("", "yyyyMMMdd HH:mm:ss");
deployTime = dateUnit.parseString(deployStr, 0);
currRelease = new Release(appName, verName, deployTime);
buildTime = 0;
if (buildStr != null)
buildTime = dateUnit.parseString(buildStr, 0);
currRelease = new Release(appName, verName, buildTime);
// Form the PickReleasePanel
pickVersionPanel = new PickReleasePanel(parentFrame, currRelease);
@@ -168,27 +215,46 @@ public class DistMakerEngine
{
List<Release> fullList;
Release chosenItem;
File destPath;
File installPath, destPath;
String appName;
boolean isPass;
// Determine the destination where to drop the release
destPath = new File(DistUtils.getAppPath().getParentFile(), "delta");
// Determine the path to download updates
installPath = DistUtils.getAppPath().getParentFile();
destPath = new File(installPath, "delta");
// Status info
appName = currRelease.getName();
aTask.infoAppendln("Application: " + appName + " - " + currRelease.getVersion() + '\n');
aTask.infoAppendln("Application: " + appName + " - " + currRelease.getVersion());
// Retrieve the list of available releases
aTask.infoAppendln("Checking for updates...\n");
fullList = DistUtils.getAvailableReleases(aTask, updateUrl, appName, refCredential);
if (fullList == null)
{
aTask.abort();
return;
}
// Prompt the user for the Release
aTask.infoAppendln("Please select the release to install...");
pickVersionPanel.setConfiguration(fullList);
pickVersionPanel.setVisibleAsModal();
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
pickVersionPanel.setVisibleAsModal();
}
});
}
catch (Exception aExp)
{
aExp.printStackTrace();
}
// pickVersionPanel.setVisibleAsModal();
chosenItem = pickVersionPanel.getChosenItem();
if (chosenItem == null)
{
@@ -196,10 +262,12 @@ public class DistMakerEngine
aTask.abort();
return;
}
// Log the user chosen action
aTask.infoAppendln("\tRelease chosen: " + chosenItem.getVersion());
if (currRelease.getDeployTime() < chosenItem.getDeployTime())
if (currRelease.getBuildTime() < chosenItem.getBuildTime())
aTask.infoAppendln("\t" + appName + " will be updated...");
else
aTask.infoAppendln("\t" + appName + " will be reverted...");
@@ -210,11 +278,12 @@ public class DistMakerEngine
{
IoUtil.deleteDirectory(destPath);
aTask.infoAppendln("Application update aborted.");
aTask.abort();
return;
}
// Notify the user of success
aTask.infoAppendln(appName + " has been updated to version: " + chosenItem.getDeployTime() + ".");
aTask.infoAppendln(appName + " has been updated to version: " + chosenItem.getVersion() + ".");
aTask.infoAppendln("These updates will become active when " + appName + " is restarted.");
}
@@ -233,12 +302,15 @@ public class DistMakerEngine
// Retrieve the list of files to download
fileList = DistUtils.getFileListForRelease(aTask, updateUrl, aRelease, destPath, refCredential);
if (fileList == null)
return false;
// Compute some baseline vars
baseUrlStr = updateUrl.toString() + "/" + aRelease.getVersion() + "/";
clipLen = destPath.getAbsolutePath().length();
baseUrlStr = updateUrl.toString() + "/" + aRelease.getName() + "/" + aRelease.getVersion() + "/" + "delta/";
clipLen = destPath.getAbsolutePath().length() + 1;
// Download the individual files
aTask.infoAppendln("Downloading release: " + aRelease.getVersion() + " Files: " + fileList.size());
for (File aFile : fileList)
{
// Bail if we have been aborted
@@ -248,20 +320,38 @@ public class DistMakerEngine
srcUrlStr = baseUrlStr + aFile.getAbsolutePath().substring(clipLen);
srcUrl = IoUtil.createURL(srcUrlStr);
aTask.infoAppendln(srcUrlStr + " -> " + aFile);
aTask.infoAppendln("\t" + srcUrlStr + " -> " + aFile);
aFile.getParentFile().mkdirs();
isPass = IoUtil.copyUrlToFile(srcUrl, aFile);// , Username, Password);
if (isPass == false)
{
aFile.delete();
aTask.infoAppendln("Failed to download resource: " + srcUrl);
aTask.infoAppendln("\tSource: " + srcUrlStr);
aTask.infoAppendln("\tDest: " + aFile);
return false;
}
// isPass = IoUtil.copyUrlToFile(srcUrl, aFile);// , Username, Password);
// if (isPass == false)
// {
// aFile.delete();
// aTask.infoAppendln("Failed to download resource: " + srcUrl);
// aTask.infoAppendln("\tSource: " + srcUrlStr);
// aTask.infoAppendln("\tDest: " + aFile);
// return false;
// }
}
return true;
}
/**
* Helper method to display an erroneous DistMaker configuration
*/
private void displayErrorDialog(String aMsg)
{
// Default message
if (aMsg == null)
{
aMsg = "This application does not appear to be a properly configured DistMaker application.\n\n";
aMsg += "Please check installation configuration.";
}
// Display the message
msgPanel.setTitle("Application Updater");
msgPanel.setInfo(aMsg);
msgPanel.setVisible(true);
}
}

View File

@@ -1,14 +1,13 @@
package distMaker;
import glum.gui.GuiUtil;
import glum.io.IoUtil;
import glum.net.*;
import glum.reflect.ReflectUtil;
import glum.task.Task;
import glum.unit.DateUnit;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.*;
import java.util.List;
import com.google.common.collect.Lists;
@@ -23,7 +22,7 @@ public class DistUtils
*/
public static File getAppPath()
{
File jarPath, currPath, testPath;
File jarPath, currPath, testFile;
jarPath = ReflectUtil.getInstalledRootDir(DistUtils.class);
@@ -31,15 +30,51 @@ public class DistUtils
while (currPath != null)
{
currPath = currPath.getParentFile();
testPath = new File(currPath, "app.cfg");
if (testPath.isFile() == true)
return testPath;
testFile = new File(currPath, "app.cfg");
if (testFile.isFile() == true)
return currPath;
}
// Return default location
return jarPath.getParentFile().getParentFile();
}
/**
* Utility method to determine if this appears to be a delevolper's release (run from eclipse)
*/
public static boolean isDevelopersRelease(Class<?> refClass)
{
String dataPath;
URL aUrl;
// Attempt to determine the default data directory
aUrl = refClass.getResource(refClass.getSimpleName() + ".class");
// System.out.println("URL:" + aUrl);
try
{
dataPath = aUrl.toURI().toString();
dataPath = URLDecoder.decode(dataPath, "UTF-8");
}
catch (Exception aExp)
{
dataPath = aUrl.getPath();
try
{
dataPath = URLDecoder.decode(dataPath, "UTF-8");
}
catch (Exception aExp2)
{
;
}
}
// Remove the jar file component from the path "!*.jar"
if (dataPath.lastIndexOf("!") != -1)
return false;
else
return true;
}
/**
* Returns the list of available releases.
*/
@@ -50,6 +85,7 @@ public class DistUtils
URLConnection connection;
InputStream inStream;
BufferedReader bufReader;
DateUnit dateUnit;
String errMsg;
errMsg = null;
@@ -63,7 +99,7 @@ public class DistUtils
{
String[] tokens;
String strLine, verName;
long deployTime;
long buildTime;
// Read the contents of the file
connection = catUrl.openConnection();
@@ -90,8 +126,11 @@ public class DistUtils
// if (tokens.length == 2)
{
verName = tokens[0];
deployTime = GuiUtil.readLong(tokens[1], 0);
fullList.add(new Release(appName, verName, deployTime));
dateUnit = new DateUnit("", "yyyyMMMdd HH:mm:ss");
buildTime = dateUnit.parseString(tokens[1], 0);
fullList.add(new Release(appName, verName, buildTime));
}
}
}
@@ -190,7 +229,7 @@ public class DistUtils
if (strLine == null)
break;
tokens = strLine.split(",");
tokens = strLine.split("\\s+");
if (strLine.isEmpty() == true || strLine.startsWith("#") == true)
; // Nothing to do
else if (tokens.length != 2)

View File

@@ -2,6 +2,6 @@ package distMaker;
public enum LookUp
{
VersionName,
DeployTime,
BuildTime,
Version,
}

View File

@@ -2,18 +2,17 @@ package distMaker;
import glum.database.QueryItem;
public class Release implements Comparable<Release>, QueryItem<LookUp>
{
private String appName;
private String verName;
private long deployTime;
private String version;
private long buildTime;
public Release(String aAppName, String aVerName, long aDeployTime)
public Release(String aAppName, String aVersion, long aBuildTime)
{
appName = aAppName;
verName = aVerName;
deployTime = aDeployTime;
version = aVersion;
buildTime = aBuildTime;
}
/**
@@ -29,23 +28,23 @@ public class Release implements Comparable<Release>, QueryItem<LookUp>
*/
public String getVersion()
{
return verName;
return version;
}
/**
* Returns the time at which this version was deployed (made available to the public/customer)
* Returns the time at which this version was built.
*/
public long getDeployTime()
public long getBuildTime()
{
return deployTime;
return buildTime;
}
@Override
public int compareTo(Release o)
{
if (deployTime < o.deployTime)
if (buildTime < o.buildTime)
return -1;
else if (deployTime > o.deployTime)
else if (buildTime > o.buildTime)
return 1;
return 0;
@@ -56,11 +55,11 @@ public class Release implements Comparable<Release>, QueryItem<LookUp>
{
switch (aEnum)
{
case DeployTime:
return deployTime;
case BuildTime:
return buildTime;
case VersionName:
return verName;
case Version:
return version;
default:
return null;
@@ -73,4 +72,44 @@ public class Release implements Comparable<Release>, QueryItem<LookUp>
throw new RuntimeException("Unsupported operation");
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((appName == null) ? 0 : appName.hashCode());
result = prime * result + (int)(buildTime ^ (buildTime >>> 32));
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Release other = (Release)obj;
if (appName == null)
{
if (other.appName != null)
return false;
}
else if (!appName.equals(other.appName))
return false;
if (buildTime != other.buildTime)
return false;
if (version == null)
{
if (other.version != null)
return false;
}
else if (!version.equals(other.version))
return false;
return true;
}
}