diff --git a/GreenshotPhotobucketPlugin/PhotobucketDestination.cs b/GreenshotPhotobucketPlugin/PhotobucketDestination.cs
index db3c031bb..b4641791f 100644
--- a/GreenshotPhotobucketPlugin/PhotobucketDestination.cs
+++ b/GreenshotPhotobucketPlugin/PhotobucketDestination.cs
@@ -19,7 +19,9 @@
* along with this program. If not, see .
*/
using System.ComponentModel;
+using System.Collections.Generic;
using System.Drawing;
+
using Greenshot.IniFile;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
@@ -32,9 +34,16 @@ namespace GreenshotPhotobucketPlugin {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PhotobucketDestination));
private static PhotobucketConfiguration config = IniConfig.GetIniSection();
private PhotobucketPlugin plugin = null;
+ private string albumPath = null;
- public PhotobucketDestination(PhotobucketPlugin plugin) {
+ ///
+ /// Create a Photobucket destination, which also has the path to the album in it
+ ///
+ ///
+ /// path to the album, null for default
+ public PhotobucketDestination(PhotobucketPlugin plugin, string albumPath) {
this.plugin = plugin;
+ this.albumPath = albumPath;
}
public override string Designation {
@@ -45,6 +54,9 @@ namespace GreenshotPhotobucketPlugin {
public override string Description {
get {
+ if (albumPath != null) {
+ return albumPath;
+ }
return Language.GetString("photobucket", LangKey.upload_menu_item);
}
}
@@ -55,11 +67,35 @@ namespace GreenshotPhotobucketPlugin {
return (Image)resources.GetObject("Photobucket");
}
}
+
+ public override bool isDynamic {
+ get {
+ return true;
+ }
+ }
+ public override IEnumerable DynamicDestinations() {
+ List albums = PhotobucketUtils.RetrievePhotobucketAlbums();
+
+ if (albums == null || albums.Count == 0) {
+ yield break;
+ }
+ foreach(string album in albums) {
+ yield return new PhotobucketDestination(plugin, album);
+ }
+ }
+
+ ///
+ /// Export the capture to Photobucket
+ ///
+ ///
+ ///
+ ///
+ ///
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
string uploadURL = null;
- bool uploaded = plugin.Upload(captureDetails, surface, out uploadURL);
+ bool uploaded = plugin.Upload(captureDetails, surface, albumPath, out uploadURL);
if (uploaded) {
exportInformation.ExportMade = true;
exportInformation.Uri = uploadURL;
diff --git a/GreenshotPhotobucketPlugin/PhotobucketInfo.cs b/GreenshotPhotobucketPlugin/PhotobucketInfo.cs
index 9f639aab5..89c6010fa 100644
--- a/GreenshotPhotobucketPlugin/PhotobucketInfo.cs
+++ b/GreenshotPhotobucketPlugin/PhotobucketInfo.cs
@@ -26,7 +26,7 @@ namespace GreenshotPhotobucketPlugin
///
/// Description of PhotobucketInfo.
///
- public class PhotobucketInfo : IDisposable {
+ public class PhotobucketInfo {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PhotobucketInfo));
private string original;
@@ -51,25 +51,11 @@ namespace GreenshotPhotobucketPlugin
}
///
- /// The public accessible Dispose
- /// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
+ /// Parse the upload response
///
- public void Dispose() {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// This Dispose is called from the Dispose and the Destructor.
- /// When disposing==true all non-managed resources should be freed too!
- ///
- ///
- protected virtual void Dispose(bool disposing) {
- if (disposing) {
- }
- }
-
- public static PhotobucketInfo ParseResponse(string response) {
+ /// XML
+ /// PhotobucketInfo object
+ public static PhotobucketInfo FromUploadResponse(string response) {
LOG.Debug(response);
PhotobucketInfo PhotobucketInfo = new PhotobucketInfo();
try {
diff --git a/GreenshotPhotobucketPlugin/PhotobucketPlugin.cs b/GreenshotPhotobucketPlugin/PhotobucketPlugin.cs
index cd1f8418f..f1d0b1568 100644
--- a/GreenshotPhotobucketPlugin/PhotobucketPlugin.cs
+++ b/GreenshotPhotobucketPlugin/PhotobucketPlugin.cs
@@ -45,7 +45,7 @@ namespace GreenshotPhotobucketPlugin {
}
public IEnumerable Destinations() {
- yield return new PhotobucketDestination(this);
+ yield return new PhotobucketDestination(this, null);
}
public IEnumerable Processors() {
@@ -114,7 +114,7 @@ namespace GreenshotPhotobucketPlugin {
/// ISurface
/// out string for the url
/// true if the upload succeeded
- public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadURL) {
+ public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, string albumPath, out string uploadURL) {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
try {
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
@@ -123,7 +123,7 @@ namespace GreenshotPhotobucketPlugin {
// Run upload in the background
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("photobucket", LangKey.communication_wait),
delegate() {
- photobucketInfo = PhotobucketUtils.UploadToPhotobucket(surfaceToUpload, outputSettings, captureDetails.Title, filename);
+ photobucketInfo = PhotobucketUtils.UploadToPhotobucket(surfaceToUpload, outputSettings, albumPath, captureDetails.Title, filename);
}
);
// This causes an exeption if the upload failed :)
diff --git a/GreenshotPhotobucketPlugin/PhotobucketUtils.cs b/GreenshotPhotobucketPlugin/PhotobucketUtils.cs
index 5dcfbf980..1d84bad89 100644
--- a/GreenshotPhotobucketPlugin/PhotobucketUtils.cs
+++ b/GreenshotPhotobucketPlugin/PhotobucketUtils.cs
@@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.Xml;
using Greenshot.IniFile;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
@@ -29,21 +30,69 @@ namespace GreenshotPhotobucketPlugin {
///
/// Description of PhotobucketUtils.
///
- public class PhotobucketUtils {
+ public static class PhotobucketUtils {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PhotobucketUtils));
- private static PhotobucketConfiguration config = IniConfig.GetIniSection();
-
- private PhotobucketUtils() {
- }
+ private static readonly PhotobucketConfiguration config = IniConfig.GetIniSection();
///
/// Do the actual upload to Photobucket
/// For more details on the available parameters, see: http://api.Photobucket.com/resources_anon
///
/// PhotobucketResponse
- public static PhotobucketInfo UploadToPhotobucket(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
+ public static PhotobucketInfo UploadToPhotobucket(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string albumPath, string title, string filename) {
string responseString;
+
+ if (string.IsNullOrEmpty(albumPath)) {
+ albumPath = "!";
+ }
+ OAuthSession oAuth = createSession();
+
+ IDictionary signedParameters = new Dictionary();
+ // add album
+ if (albumPath == null) {
+ signedParameters.Add("id", config.Username);
+ } else {
+ signedParameters.Add("id", albumPath);
+ }
+ // add type
+ signedParameters.Add("type", "image");
+ // add title
+ if (title != null) {
+ signedParameters.Add("title", title);
+ }
+ // add filename
+ if (filename != null) {
+ signedParameters.Add("filename", filename);
+ }
+ IDictionary unsignedParameters = new Dictionary();
+ // Add image
+ unsignedParameters.Add("uploadfile", new SurfaceContainer(surfaceToUpload, outputSettings, filename));
+ try {
+ string apiUrl = "http://api.photobucket.com/album/!/upload";
+ responseString = oAuth.MakeOAuthRequest(HTTPMethod.POST, apiUrl, apiUrl.Replace("api.photobucket.com", config.SubDomain), signedParameters, unsignedParameters, null);
+ } catch (Exception ex) {
+ LOG.Error("Error uploading to Photobucket.", ex);
+ throw ex;
+ } finally {
+ if (!string.IsNullOrEmpty(oAuth.Token)) {
+ config.Token = oAuth.Token;
+ }
+ if (!string.IsNullOrEmpty(oAuth.TokenSecret)) {
+ config.TokenSecret = oAuth.TokenSecret;
+ }
+ }
+ LOG.Info(responseString);
+ PhotobucketInfo PhotobucketInfo = PhotobucketInfo.FromUploadResponse(responseString);
+ LOG.Debug("Upload to Photobucket was finished");
+ return PhotobucketInfo;
+ }
+
+ ///
+ /// Helper method to create an OAuth session object for contacting the Photobucket API
+ ///
+ /// OAuthSession
+ private static OAuthSession createSession() {
OAuthSession oAuth = new OAuthSession(PhotobucketCredentials.ConsumerKey, PhotobucketCredentials.ConsumerSecret);
oAuth.CheckVerifier = false;
// This url is configured in the Photobucket API settings in the Photobucket site!!
@@ -77,26 +126,22 @@ namespace GreenshotPhotobucketPlugin {
}
oAuth.Token = config.Token;
oAuth.TokenSecret = config.TokenSecret;
+ return oAuth;
+ }
+
+ ///
+ /// Get list of photobucket albums
+ ///
+ /// List
+ public static List RetrievePhotobucketAlbums() {
+ string responseString;
+
+ OAuthSession oAuth = createSession();
IDictionary signedParameters = new Dictionary();
- // add album
- signedParameters.Add("id", config.Username);
- // add type
- signedParameters.Add("type", "image");
- // add title
- if (title != null) {
- signedParameters.Add("title", title);
- }
- // add filename
- if (filename != null) {
- signedParameters.Add("filename", filename);
- }
- IDictionary unsignedParameters = new Dictionary();
- // Add image
- unsignedParameters.Add("uploadfile", new SurfaceContainer(surfaceToUpload, outputSettings, filename));
try {
- string apiUrl = "http://api.photobucket.com/album/!/upload";
- responseString = oAuth.MakeOAuthRequest(HTTPMethod.POST, apiUrl, apiUrl.Replace("api.photobucket.com", config.SubDomain), signedParameters, unsignedParameters, null);
+ string apiUrl = string.Format("http://api.photobucket.com/album/{0}", config.Username);
+ responseString = oAuth.MakeOAuthRequest(HTTPMethod.GET, apiUrl, apiUrl.Replace("api.photobucket.com", config.SubDomain), signedParameters, null, null);
} catch (Exception ex) {
LOG.Error("Error uploading to Photobucket.", ex);
throw ex;
@@ -108,10 +153,43 @@ namespace GreenshotPhotobucketPlugin {
config.TokenSecret = oAuth.TokenSecret;
}
}
- LOG.Info(responseString);
- PhotobucketInfo PhotobucketInfo = PhotobucketInfo.ParseResponse(responseString);
+ try {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(responseString);
+ List albums = new List();
+ recurseAlbums(albums, null, doc.GetElementsByTagName("content").Item(0).ChildNodes);
+ LOG.DebugFormat("Albums: {0}", string.Join(",", albums.ToArray()));
+ return albums;
+ } catch(Exception e) {
+ LOG.Error("Error while Reading albums: ", e);
+ }
+
LOG.Debug("Upload to Photobucket was finished");
- return PhotobucketInfo;
+ return null;
+ }
+
+ ///
+ /// Parse the album nodes recursively
+ ///
+ ///
+ ///
+ ///
+ private static void recurseAlbums(Listalbums, string path, XmlNodeList nodes) {
+ foreach(XmlNode node in nodes) {
+ if (node.Name != "album") {
+ continue;
+ }
+ string currentAlbum = node.Attributes["name"].Value;
+ string currentPath = currentAlbum;
+ if (path != null && path.Length > 0) {
+ currentPath = string.Format("{0}/{1}", path, currentAlbum);
+ }
+
+ albums.Add(currentPath);
+ if (node.Attributes["subalbum_count"] != null && node.Attributes["subalbum_count"].Value != "0") {
+ recurseAlbums(albums, currentPath, node.ChildNodes);
+ }
+ }
}
}
}