diff --git a/MinusEngine/MinusApi.cs b/MinusEngine/MinusApi.cs index 258c9ab..fc61d58 100644 --- a/MinusEngine/MinusApi.cs +++ b/MinusEngine/MinusApi.cs @@ -52,6 +52,8 @@ public class MinusApi #region Constants public static readonly String USER_AGENT = "MinusEngine_0.2"; public static readonly String BASE_URL = "http://minus.com/api/"; + public static readonly String PAGE_BASE_URL = "http://minus.com"; + public static readonly String PAGE_COOKIE = "__utmc=125622038;"; public static readonly Uri CREATE_GALLERY_URL = new Uri(BASE_URL + "CreateGallery"); public static readonly Uri UPLOAD_ITEM_URL = new Uri(BASE_URL + "UploadItem"); public static readonly Uri SAVE_GALLERY_URL = new Uri(BASE_URL + "SaveGallery"); @@ -107,27 +109,15 @@ public MinusApi(String apiKey) #endregion #region Public methods - - /// - /// Creates an empty new gallery. - /// - public void CreateGallery() - { - CreateGallery(null); - } - + /// /// Creates an empty new gallery. /// public void CreateGallery(String cookieHeader) { - CookieAwareWebClient client = this.CreateAndSetupWebClient(); - if (!String.IsNullOrEmpty(cookieHeader)) - { - client.setCookieHeader(new Uri(BASE_URL), cookieHeader); - } - + CookieAwareWebClient client = this.CreateAndSetupWebClient(cookieHeader); + client.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e) { if (e.Error != null) { @@ -197,26 +187,30 @@ public void CreateGallery(String cookieHeader) /// abort this operation. /// #if !WINDOWS_PHONE - public void UploadItem(String editorId, String key, String filename, String desiredFilename = null) + public void UploadItem(String cookieHeader, String editorId, String key, String filename, String desiredFilename = null) { // Not worth checking for file existence or other stuff, as either Path.GetFileName or the upload // will check & fail String name = desiredFilename == null ? Path.GetFileName(filename) : desiredFilename; Stream data = new FileStream(filename, FileMode.Open, FileAccess.Read); - UploadItem(editorId, key, name, data); + UploadItem(cookieHeader, editorId, key, name, data); } #endif - public void UploadItem(String editorId, String key, String filename, Stream data) + public void UploadItem(String cookieHeader, String editorId, String key, String filename, Stream data) { UriBuilder ub = new UriBuilder(UPLOAD_ITEM_URL); - ub.Query = string.Format("filename={0}&key={1}&editor_id={2}", filename, key, editorId); + ub.Query = string.Format("filename={0}&key={1}&editor_id={2}&reader_id={2}", filename, key, editorId); try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ub.Uri); request.Method = "POST"; - + request.ContentType = "application/octet-stream"; + request.Headers.Add("Content-Disposition", "attachment; filename=" + filename); + request.CookieContainer = new CookieContainer(); + request.CookieContainer.SetCookies(new Uri(BASE_URL), cookieHeader); + ThreadPool.QueueUserWorkItem((object state) => { @@ -272,11 +266,11 @@ public void UploadItem(String editorId, String key, String filename, Stream data /// If you fail to include items that were uploaded to this gallery, those items will be /// discarded by the server. /// - public void SaveGallery(String name, String galleryEditorId, String key, String[] items) + public void SaveGallery(String cookieHeader, String name, String galleryEditorId, String key, String[] items) { // Get a pre-configured web client - WebClient client = this.CreateAndSetupWebClient(); - + CookieAwareWebClient client = this.CreateAndSetupWebClient(cookieHeader); + string jsonItems; // build the item list (the order in which the items will be shown) @@ -299,7 +293,7 @@ public void SaveGallery(String name, String galleryEditorId, String key, String[ .Append("&items=").Append(UrlEncode(jsonItems)); client.Headers["Content-Type"] = "application/x-www-form-urlencoded"; - + // register the completion/error listener client.UploadStringCompleted += delegate(object sender, UploadStringCompletedEventArgs e) { @@ -353,14 +347,14 @@ public void SaveGallery(String name, String galleryEditorId, String key, String[ /// Retrieve all items in a gallery, along with some other info (url and title). /// /// The reader id (public) of the gallery. - public void GetItems(String galleryReaderId) + public void GetItems(String cookieHeader, String galleryReaderId) { if (String.IsNullOrEmpty(galleryReaderId)) { throw new ArgumentException("Gallery Reader Id cannot be null or empty"); } - WebClient client = this.CreateAndSetupWebClient(); + WebClient client = this.CreateAndSetupWebClient(cookieHeader); client.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e) { if (e.Error != null) @@ -409,6 +403,18 @@ public void GetItems(String galleryReaderId) } } + /// + /// Sign in as guest + /// + public void SignIn() + { + SignInResult result = new SignInResult(true) + { + CookieHeaders = PAGE_COOKIE + }; + TriggerSignInComplete(result); + } + /// /// Signs into minus /// @@ -495,7 +501,7 @@ public void MyGalleries(String cookieHeader) throw new ArgumentException("Cookie Header cannot be null or empty"); } - CookieAwareWebClient client = this.CreateAndSetupWebClient(); + CookieAwareWebClient client = this.CreateAndSetupWebClient(cookieHeader); client.setCookieHeader(new Uri(BASE_URL), cookieHeader); client.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e) { @@ -585,6 +591,10 @@ public static String UrlEncode(String parameter) #region Private helpers private CookieAwareWebClient CreateAndSetupWebClient() + { + return CreateAndSetupWebClient(null); + } + private CookieAwareWebClient CreateAndSetupWebClient(String cookieHeader) { CookieAwareWebClient client = new CookieAwareWebClient(); #if !WINDOWS_PHONE @@ -594,6 +604,11 @@ private CookieAwareWebClient CreateAndSetupWebClient() } #endif client.Headers["User-Agent"] = USER_AGENT; + if(cookieHeader != null) + { + client.setCookieHeader(new Uri(BASE_URL), cookieHeader); + } + return client; } diff --git a/MinusEngine/Properties/AssemblyInfo.cs b/MinusEngine/Properties/AssemblyInfo.cs index e8f6bb5..7b65578 100644 --- a/MinusEngine/Properties/AssemblyInfo.cs +++ b/MinusEngine/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/MinusEngineTestApp/Program.cs b/MinusEngineTestApp/Program.cs index fd5c458..f5aad7f 100644 --- a/MinusEngineTestApp/Program.cs +++ b/MinusEngineTestApp/Program.cs @@ -36,12 +36,39 @@ static void Main(string[] args) // Pick one of these methods below to test the features independently //TestAuth(); //TestGetItems(); - TestAll(); + //TestAll(); + TestGuestUpload(); // Sleep a bit so you can check the output... Thread.Sleep(40000); } + private static void TestGuestUpload() + { + // create the API + MinusApi api = new MinusApi(API_KEY); + + CreateGalleryResult galleryCreated = null; + + api.SignInComplete += delegate(MinusApi sender, SignInResult result) + { + api.CreateGallery(result.CookieHeaders); + }; + + api.CreateGalleryComplete += delegate(MinusApi sender, CreateGalleryResult result) + { + // gallery created, trigger upload of the first file + galleryCreated = result; + Console.WriteLine("Gallery created! " + result); + Thread.Sleep(1000); + Console.WriteLine("Uploading files..."); + //api.UploadItem(result.EditorId, result.Key, items[0]); + }; + + // this is the call that actually triggers the whole program + api.SignIn(); + } + private static void TestAuth() { // create the API @@ -103,9 +130,14 @@ private static void TestGetItems() Console.WriteLine("Failed to get items from gallery...\n" + e.Message); }; + api.SignInComplete += delegate(MinusApi sender, SignInResult result) + { + api.GetItems(result.CookieHeaders, "mvgkRZC"); + }; + // trigger the GetItems operation - notice the extra "m" in there. // while the REAL reader id is "vgkRZC", the API requires you to put the extra "m" in there - api.GetItems("mvgkRZC"); + } /// @@ -114,91 +146,89 @@ private static void TestGetItems() /// Make sure you change the values of the items in the "items" array to match actually valid files or this /// will fail. /// - private static void TestAll() - { - // The call that triggers the program is the near the end of this method - // (the rest is pretty much setup to react to events) - - // create the API - MinusApi api = new MinusApi(API_KEY); - - // Prepare the items to be uploaded - String[] items = - { - @"C:\Users\bruno\Desktop\clown.png", - @"C:\Users\bruno\Desktop\small.png" - }; - IList uploadedItems = new List(items.Length); - - // create a couple of things we're going to need between requests - CreateGalleryResult galleryCreated = null; - - // set up the listeners for CREATE - api.CreateGalleryFailed += delegate(MinusApi sender, Exception e) - { - // don't do anything else... - Console.WriteLine("Failed to create gallery..." + e.Message); - }; - api.CreateGalleryComplete += delegate(MinusApi sender, CreateGalleryResult result) - { - // gallery created, trigger upload of the first file - galleryCreated = result; - Console.WriteLine("Gallery created! " + result); - Thread.Sleep(1000); - Console.WriteLine("Uploading files..."); - api.UploadItem(result.EditorId, result.Key, items[0]); - }; - - // set up the listeners for UPLOAD - api.UploadItemFailed += delegate(MinusApi sender, Exception e) - { - // don't do anything else... - Console.WriteLine("Upload failed: " + e.Message); - }; - api.UploadItemComplete += delegate(MinusApi sender, UploadItemResult result) - { - // upload complete, either trigger another upload or save the gallery if all files have been uploaded - Console.WriteLine("Upload successful: " + result); - uploadedItems.Add(result.Id); - if (uploadedItems.Count == items.Length) - { - // if all the elements are uploaded, then save the gallery - Console.WriteLine("All uploads complete, saving gallery..."); - api.SaveGallery("testGallery", galleryCreated.EditorId, galleryCreated.Key, uploadedItems.ToArray()); - } - else - { - // otherwise just keep uploading - Console.WriteLine("Uploading item " + (uploadedItems.Count + 1)); - api.UploadItem(galleryCreated.EditorId, galleryCreated.Key, items[uploadedItems.Count]); - } - }; - - // set up the listeners for SAVE - api.SaveGalleryFailed += delegate(MinusApi sender, Exception e) - { - Console.WriteLine("Failed to save gallery... " + e.Message); - }; - api.SaveGalleryComplete += delegate(MinusApi sender) - { - // The extra "m" is appended because minus uses the first character to determine the type of data - // you're accessing (image, gallery, etc) and route you accordingly. - Console.WriteLine("Gallery saved! You can now access it at http://min.us/m" + galleryCreated.ReaderId); - api.SignIn("123test123", "123test123"); - }; - - //set up listeners for SignIn - api.SignInFailed += delegate(MinusApi sender, Exception e) - { - Console.WriteLine("Failed to Sign In... " + e.Message); - }; - api.SignInComplete += delegate(MinusApi sender, SignInResult result) - { - Console.WriteLine("Signed In: " + result.Success); - }; - - // this is the call that actually triggers the whole program - api.CreateGallery(); - } + //private static void TestAll() + //{ + // // The call that triggers the program is the near the end of this method + // // (the rest is pretty much setup to react to events) + + // // create the API + // MinusApi api = new MinusApi(API_KEY); + + // // Prepare the items to be uploaded + // String[] items = + // { + // @"e:\src\cs\Koffeinfrei\MinusShare\lib\MinusEngine\README.md" + // }; + // IList uploadedItems = new List(items.Length); + + // // create a couple of things we're going to need between requests + // CreateGalleryResult galleryCreated = null; + + // // set up the listeners for CREATE + // api.CreateGalleryFailed += delegate(MinusApi sender, Exception e) + // { + // // don't do anything else... + // Console.WriteLine("Failed to create gallery..." + e.Message); + // }; + // api.CreateGalleryComplete += delegate(MinusApi sender, CreateGalleryResult result) + // { + // // gallery created, trigger upload of the first file + // galleryCreated = result; + // Console.WriteLine("Gallery created! " + result); + // Thread.Sleep(1000); + // Console.WriteLine("Uploading files..."); + // api.UploadItem(result.EditorId, result.Key, items[0]); + // }; + + // // set up the listeners for UPLOAD + // api.UploadItemFailed += delegate(MinusApi sender, Exception e) + // { + // // don't do anything else... + // Console.WriteLine("Upload failed: " + e.Message); + // }; + // api.UploadItemComplete += delegate(MinusApi sender, UploadItemResult result) + // { + // // upload complete, either trigger another upload or save the gallery if all files have been uploaded + // Console.WriteLine("Upload successful: " + result); + // uploadedItems.Add(result.Id); + // if (uploadedItems.Count == items.Length) + // { + // // if all the elements are uploaded, then save the gallery + // Console.WriteLine("All uploads complete, saving gallery..."); + // api.SaveGallery("testGallery", galleryCreated.EditorId, galleryCreated.Key, uploadedItems.ToArray()); + // } + // else + // { + // // otherwise just keep uploading + // Console.WriteLine("Uploading item " + (uploadedItems.Count + 1)); + // api.UploadItem(galleryCreated.EditorId, galleryCreated.Key, items[uploadedItems.Count]); + // } + // }; + + // // set up the listeners for SAVE + // api.SaveGalleryFailed += delegate(MinusApi sender, Exception e) + // { + // Console.WriteLine("Failed to save gallery... " + e.Message); + // }; + // api.SaveGalleryComplete += delegate(MinusApi sender) + // { + // // The extra "m" is appended because minus uses the first character to determine the type of data + // // you're accessing (image, gallery, etc) and route you accordingly. + // Console.WriteLine("Gallery saved! You can now access it at http://min.us/m" + galleryCreated.ReaderId); + // }; + + // //set up listeners for SignIn + // api.SignInFailed += delegate(MinusApi sender, Exception e) + // { + // Console.WriteLine("Failed to Sign In... " + e.Message); + // }; + // api.SignInComplete += delegate(MinusApi sender, SignInResult result) + // { + // api.CreateGallery(result.CookieHeaders); + // }; + + // // this is the call that actually triggers the whole program + // api.SignIn("123test123", "123test123"); + //} } }