From cf4e32240309d18a213026b221fd59d39b523428 Mon Sep 17 00:00:00 2001 From: Jesse Morgan Date: Wed, 12 Dec 2012 18:03:55 -0800 Subject: Add ProgressInterface base class and progress on UploadTask. --- .../podcastuploader/control/ObservableTask.java | 40 ++++++++++ .../podcastuploader/control/UploadTask.java | 85 +++++++++++++++++++++- .../podcastuploader/ui/ProgressInterface.java | 76 +++++++++++++++++++ .../podcastuploader/ui/ProgressWindow.java | 2 +- 4 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 src/net/jesterpm/podcastuploader/control/ObservableTask.java create mode 100644 src/net/jesterpm/podcastuploader/ui/ProgressInterface.java diff --git a/src/net/jesterpm/podcastuploader/control/ObservableTask.java b/src/net/jesterpm/podcastuploader/control/ObservableTask.java new file mode 100644 index 0000000..381145e --- /dev/null +++ b/src/net/jesterpm/podcastuploader/control/ObservableTask.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012 Jesse Morgan + */ + +package net.jesterpm.podcastuploader.control; + +import java.util.Observable; + +/** + * ProgressInterface is an abstract based class for any interface that + * provides progress notification. The class tracks the progress of multiple + * simultaneous tasks and aggregates their progress. + * + * @author Jesse Morgan + */ +public abstract class ObservableTask extends Observable { + private float mProgress; + + public ObservableTask() { + mProgress = 0; + } + + /** + * @return The percentage complete as a float between 0 and 1. + */ + public float getProgress() { + return mProgress; + } + + /** + * Set the current progress. + * + * @param percentComplete The percentage complete as a float between 0 and 1. + */ + protected void setProgress(float percentComplete) { + mProgress = percentComplete; + setChanged(); + notifyObservers(); + } +} diff --git a/src/net/jesterpm/podcastuploader/control/UploadTask.java b/src/net/jesterpm/podcastuploader/control/UploadTask.java index 09200e1..6268566 100644 --- a/src/net/jesterpm/podcastuploader/control/UploadTask.java +++ b/src/net/jesterpm/podcastuploader/control/UploadTask.java @@ -26,7 +26,7 @@ public class UploadTask { /** * Progress window. */ - private final ProgressWindow mProgressWindow; + private final ProgressInterface mProgressInterface; /** * Application config. @@ -44,8 +44,10 @@ public class UploadTask { * @param win The progress window user interface. * @param dir The directory to upload. */ - public UploadTask(final Config appconfig, final ProgressWindow win, final String dir) { - mProgressWindow = win; + public UploadTask(final Config appconfig, final ProgressInterface progressInterface, + final String dir) { + + mProgressInterface = progressInterface; mAppConfig = appconfig; mMetadata = new Config(dir + METADATA_FILE); @@ -78,8 +80,85 @@ public class UploadTask { fmt = new SimpleDateFormat("yyyyMMdd"); final String baseFilename = fmt.format(date) + "-" + safeString(mMetadata.get("title")); + + // Build a list of files to upload. + Map files = getFilesToUpload(baseFilename); + // TODO: Execute all the upload tasks (in parallel?) + + // Publish the podcast metadata. + Map metadata = mMetadata.getMap().clone(); + + for (Map.Entry entry : files) { + metadata.put(entry.getKey(), entry.getValue().getRemoteFile()); + } + + PublishPodcastTask task = new PublishPodcastTask(mAppConfig, metadata); + task.run(); + } + + /** + * Build the list of S3UploadTasks to execute. + */ + private Map getFilesToUpload(final String basename) { + Map files = new HashMap(); + + String localFile; + String remoteFile; + + localFile = mMetadata.get("video"); + if (localFile != null) { + remoteFile = basename + "-video" + fileExtension(localFile); + files.put("video", new S3UploadTask(mAppConfig, localFile, remoteFile); + } + + localFile = mMetadata.get("video_lowres"); + if (localFile != null) { + remoteFile = basename + "-videolow" + fileExtension(localFile); + files.put("video_lowres", new S3UploadTask(mAppConfig, localFile, remoteFile); + } + + localFile = mMetadata.get("audio"); + if (localFile != null) { + remoteFile = basename + "-audio" + fileExtension(localFile); + files.put("audio", new S3UploadTask(mAppConfig, localFile, remoteFile); + } + + localFile = mMetadata.get("image"); + if (localFile != null) { + remoteFile = basename + "-image" + fileExtension(localFile); + files.add("image", new S3UploadTask(mAppConfig, localFile, remoteFile); + } + + localFile = mMetadata.get("mobileimage"); + if (localFile != null) { + remoteFile = basename + "-mobileimage" + fileExtension(localFile); + files.add("mobileimage", new S3UploadTask(mAppConfig, localFile, remoteFile); + } + + return files; } + /** + * @return the extension from the given filename. + */ + private String fileExtension(final String file) { + int pos = file.lastIndexOf('.'); + + if (pos == -1) { + return ""; + + } else { + return file.substring(pos); + } + } + + /** + * Transform str into a URL safe string by substituting spaces with dashes + * and dropping all other non-alphanumeric characters. + * + * @param str The String to transform. + * @return The transformed string. + */ private String safeString(String str) { char[] newStr = str.trim().toLowerCase().toCharArray(); boolean firstSpace = true; diff --git a/src/net/jesterpm/podcastuploader/ui/ProgressInterface.java b/src/net/jesterpm/podcastuploader/ui/ProgressInterface.java new file mode 100644 index 0000000..12aaabd --- /dev/null +++ b/src/net/jesterpm/podcastuploader/ui/ProgressInterface.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Jesse Morgan + */ + +package net.jesterpm.podcastuploader.ui; + +import java.util.HashMap; +import java.util.Map; +import java.util.Observer; + +import net.jesterpm.podcastuploader.control.ObserableTask; + +/** + * ProgressInterface is an abstract based class for any interface that + * provides progress notification. The class tracks the progress of multiple + * simultaneous tasks and aggregates their progress. + * + * @author Jesse Morgan + */ +public abstract class ProgressInterface implements Observer { + private Map mProgressMap; + + /** + * Creates a new ProgressInterface monitoring nothing. + */ + public ProgressInterface() { + mProgressMap = new HashMap(); + } + + /** + * Begin monitoring the given task. + * + * @param task The ObservableTask to monitor. + */ + public void monitorTask(final ObservableTask task) { + task.addObserver(this); + mProgressMap.put(task, 0); + setProgress(getProgress()); + } + + /** + * Called when the progress changes. + * + * @param progress The current percentage complete, + * indicated by a float ranging from 0 to 1. + */ + protected abstract void setProgress(float percentComplete); + + /** + * Called when the progress for a task changes. + * @param task The task that changed. + * @param arg Unused. + */ + @Override + public void update(Observable task, Object arg) { + mProgressMap.put(task, task.getProgress()); + setProgress(getProgress()); + } + + /** + * @return A float ranging from 0 to 1 representing the aggregate progress. + * If the ProgressInterface is not monitoring any tasks, this will return 0. + */ + public float getProgress() { + if (mProgressMap.size() == 0) { + return 0; + } + + float totalProgress = 0; + for (float taskProgress : mProgressMap.getValues()) { + totalProgress += taskProgress; + } + + return totalProgress / mProgressMap.size(); + } +} diff --git a/src/net/jesterpm/podcastuploader/ui/ProgressWindow.java b/src/net/jesterpm/podcastuploader/ui/ProgressWindow.java index a2cdfcc..6ac6f55 100644 --- a/src/net/jesterpm/podcastuploader/ui/ProgressWindow.java +++ b/src/net/jesterpm/podcastuploader/ui/ProgressWindow.java @@ -8,6 +8,6 @@ package net.jesterpm.podcastuploader.ui; * * @author Jesse Morgan */ -public class ProgressWindow { +public class ProgressWindow extends ProgressInterface { } -- cgit v1.2.3