public static KodakPhoto ReadFromDisk(StreamReader reader) { string data = reader.ReadLine(); if (data == null) { return null; } string[] splitData = data.Split(new string[] { "|##|" }, StringSplitOptions.None); Debug.Assert(splitData.Length == 3); KodakPhoto photo = new KodakPhoto(splitData[0]); photo.photoCaption = splitData[1]; photo.fileName = splitData[2]; return photo; }
/// <summary> /// Once a photo has been uploaded, record the fact so we can skip it next time around /// </summary> private void UpdatePhotoStatus(KodakAlbum currentAlbum, KodakPhoto currentPhoto) { string statusFile = string.Format("{0}\\Keg2Smug.{1}.status", temporaryLocation, currentAlbum.albumId); FileStream fileStream = null; if (File.Exists(statusFile)) { fileStream = File.OpenWrite(statusFile); } else { fileStream = File.Create(statusFile); } using (fileStream) { // go to the end of the file fileStream.Seek(0, SeekOrigin.End); // Write the albumId using (StreamWriter fileStreamWriter = new StreamWriter(fileStream)) { fileStreamWriter.WriteLine(currentPhoto.photoId); fileStreamWriter.Flush(); } fileStream.Close(); } }
private void TestForKodakPremierMember(KodakAlbum currentAlbum, KodakPhoto photo) { string fullPhotoUri = string.Format("http://www.kodakgallery.com/servlet/FullResDownload?collid={0}&photoid={1}", currentAlbum.albumId, photo.photoId); HttpStatusCode statusCode = HttpStatusCode.Unused; string errorString = ""; try { HttpWebRequest photoRequest = (HttpWebRequest)WebRequest.Create(fullPhotoUri); photoRequest.Method = "GET"; photoRequest.UserAgent = kegUserAgent; photoRequest.CookieContainer = new CookieContainer(); photoRequest.CookieContainer.Add(this.kodakLoginCookies); using (HttpWebResponse photoResponse = (HttpWebResponse)photoRequest.GetResponse()) { statusCode = photoResponse.StatusCode; } } catch (WebException wex) { using (HttpWebResponse response = (HttpWebResponse)wex.Response) { statusCode = response.StatusCode; } } catch (Exception ex) { errorString = ex.ToString(); } if (statusCode == HttpStatusCode.OK) { testForKodakPremierMember = true; return; } else { Console.WriteLine(); Console.WriteLine("Uh-oh! Looks like youre not a Kodak Easyshare Gallery premier member!"); Console.WriteLine("Request to Kodak Easyshare gallery failed with error {0}", (statusCode == HttpStatusCode.Unused) ? errorString : statusCode.ToString()); Environment.Exit(9); } }
/// <summary> /// Get the photo from Kodak /// </summary> private void GetPhoto(KodakAlbum currentAlbum, KodakPhoto currentPhoto) { // If the photo has already been fetched, do nothing if (File.Exists(string.Format("{0}\\{1}\\{2}.jpg", temporaryLocation, currentAlbum.albumId, currentPhoto.photoId))) { Console.WriteLine("already exists!"); return; } if (!testForKodakPremierMember) { // Check if the user is a premier kodak gallery user by trying to download the high-res photo ourselves TestForKodakPremierMember(currentAlbum, currentPhoto); } string fullPhotoUri = string.Format("http://www.kodakgallery.com/servlet/FullResDownload?collid={0}&photoid={1}", currentAlbum.albumId, currentPhoto.photoId); HttpStatusCode statusCode = HttpStatusCode.Unused; string errorString = null; try { HttpWebRequest photoRequest = (HttpWebRequest)WebRequest.Create(fullPhotoUri); photoRequest.Method = "GET"; photoRequest.UserAgent = kegUserAgent; photoRequest.CookieContainer = new CookieContainer(); photoRequest.CookieContainer.Add(this.kodakLoginCookies); using (HttpWebResponse photoResponse = (HttpWebResponse)photoRequest.GetResponse()) { if (photoResponse.StatusCode == HttpStatusCode.OK) { int contentLength = (int)photoResponse.ContentLength; byte[] buffer = new byte[contentLength]; int bytesRead = 0; using (Stream stream = photoResponse.GetResponseStream()) { while (bytesRead < contentLength) { int numBytesToRead = (contentLength - bytesRead) < 64000 ? (contentLength - bytesRead) : 64000; bytesRead += stream.Read(buffer, bytesRead, numBytesToRead); // Read 64KB chunks } Console.WriteLine("{0:D9}/{1} bytes....done!", bytesRead, contentLength); } string fileName = string.Format("{0}.jpg", currentPhoto.photoId); File.WriteAllBytes(string.Format("{0}\\{1}\\{2}.jpg", temporaryLocation, currentAlbum.albumId, currentPhoto.photoId), buffer); currentPhoto.fileName = fileName; } } } catch (WebException wex) { using (HttpWebResponse response = (HttpWebResponse)wex.Response) { statusCode = response.StatusCode; Console.WriteLine("Failed to fetch photo {0} in album {1} due to error {2}", currentPhoto.photoId, currentAlbum.albumId, statusCode); return; } } catch (Exception ex) { errorString = ex.ToString(); Console.WriteLine("Failed to fetch photo {0} in album {1} due to error {2}", currentPhoto.photoId, currentAlbum.albumId, errorString); return; } }
/// <summary> /// Fetch all the kodak albums which are to be uploaded to SmugMug /// </summary> private void FetchKodakAlbums() { Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Fetching album and photo information from Kodak Easyshare Gallery....this may take a while."); Console.WriteLine(); HttpStatusCode statusCode; for (int i = 0; i < kodakAlbums.Count; i++) { KodakAlbum currentAlbum = kodakAlbums[i]; // Check if the album metadata already exists on disk from a previous session - we dont need to get it again if (currentAlbum.ReadFromDisk(temporaryLocation)) { Console.WriteLine("Album \"{0}\" already exists on disk...will not fetch again.", currentAlbum.albumName); continue; } else { currentAlbum.CreateAlbumFolder(temporaryLocation); } Console.Write("Fetching metadata for album ({0}/{1}) - '{2}'......", i + 1, kodakAlbums.Count, currentAlbum.albumName); string albumUri = string.Format("http://www.kodakgallery.com/BrowsePhotos.jsp?collid={0}&page=1&sort_order=2", currentAlbum.albumId); string albumResponseString; if ((statusCode = HttpGet(albumUri, kegUserAgent, out albumResponseString)) != HttpStatusCode.OK) { Console.WriteLine("Failed to get album '{0}' due to error {1}", currentAlbum.albumName, statusCode); Environment.Exit(7); } // Get the album description, if requested if (albumDesc) { Regex albumDescRegex = new Regex("<p id=\"collection-description\">(.*)</p>", RegexOptions.Compiled | RegexOptions.IgnoreCase); Match albumDescMatch = albumDescRegex.Match(albumResponseString); string albumDescription = null; if (albumDescMatch.Success) { albumDescription = albumDescMatch.Groups[1].Captures[0].Value; currentAlbum.albumDescription = HttpUtility.HtmlDecode(albumDescription); } } else { currentAlbum.albumDescription = ""; } // Get all the photo ids Regex photoIdRegex = new Regex("<a class=\"thumbnail\".*photoid=([0-9]+).*>", RegexOptions.Compiled | RegexOptions.IgnoreCase); MatchCollection photoIdMatches = photoIdRegex.Matches(albumResponseString); currentAlbum.photos = new List<KodakPhoto>(); foreach (Match match in photoIdMatches) { GroupCollection groups = match.Groups; string photoId = groups[1].Captures[0].Value; KodakPhoto photo = new KodakPhoto(photoId); currentAlbum.photos.Add(photo); } Console.WriteLine("done! Got metadata for {0} photos!", currentAlbum.photos.Count); int left = Console.CursorLeft; int top = Console.CursorTop; // Get photo captions, if requested if (photoCaptions) { // Build a regex to extract the caption from each photo Regex captionRegex = new Regex("<span id=\"photoCaption\">(.*)</span>", RegexOptions.Compiled | RegexOptions.IgnoreCase); // Download caption for each photo int captionIndex = 1; foreach(KodakPhoto currentPhoto in currentAlbum.photos) { Console.SetCursorPosition(left, top); Console.Write("Getting caption for photo ({0:D4}/{1})", captionIndex++, currentAlbum.photos.Count); string photoUri = string.Format("http://www.kodakgallery.com/PhotoView.jsp?collid={0}&photoid={1}", currentAlbum.albumId, currentPhoto.photoId); string photoResponseString = null; if ((statusCode = HttpGet(photoUri, kegUserAgent, out photoResponseString)) != HttpStatusCode.OK) { Console.WriteLine("Failed to get photo {0} in album {1} with status {2}", currentPhoto.photoId, currentAlbum.albumId, statusCode); Environment.Exit(8); } // Extract the caption from the response Match captionMatch = captionRegex.Match(photoResponseString); string caption = ""; if (captionMatch.Success) { caption = captionMatch.Groups[1].Captures[0].Value; currentPhoto.photoCaption = HttpUtility.HtmlDecode(caption); } } Console.WriteLine(); } // Fetch the photos for this album int j = 0; foreach (KodakPhoto currentPhoto in currentAlbum.photos) { Console.Write("Fetching photo {0:D4}/{1}...", j++, currentAlbum.photos.Count); GetPhoto(currentAlbum, currentPhoto); } // Write the album info out to disk so we dont need to fetch it again in the future currentAlbum.WriteToDisk(temporaryLocation); } }
private int UploadPhoto(KodakAlbum currentAlbum, KodakPhoto photo, int smugAlbumID) { string filePath = string.Format("{0}\\{1}\\{2}", temporaryLocation, currentAlbum.albumId, photo.fileName); SmugUploadResponse response; try { response = smClient.ImagesUploadBinary(filePath, smLogin.Session.id, 0, smugAlbumID.ToString(), null); return response.Image.id; } catch (Exception) { Console.WriteLine("Failed to upload image {0} to SmugMug", filePath); return 0; } /* NameValueCollection queryStringCollection = new NameValueCollection(); queryStringCollection.Add("method", "smugmug.images.uploadFromURL"); queryStringCollection.Add("SessionID", smClient.SessionID); queryStringCollection.Add("APIKey", API_KEY); queryStringCollection.Add("AlbumID", smugAlbumID.ToString()); queryStringCollection.Add("Caption", photo.photoCaption); string fullPhotoUri = string.Format("http://www.kodakgallery.com/servlet/FullResDownload?collid={0}&photoid={1}&UV={2}", currentAlbum.albumId, photo.photoId, uvkey); queryStringCollection.Add("URL", fullPhotoUri); string baseUri = "http://api.smugmug.com/hack/rest/1.2.0/"; string postBody = ""; foreach (string key in queryStringCollection.AllKeys) { if (postBody.Length > 0) { postBody = string.Format("{0}&{1}={2}", postBody, key, HttpUtility.UrlEncode(queryStringCollection[key])); } else { postBody = string.Format("{0}={1}", key, HttpUtility.UrlEncode(queryStringCollection[key])); } } string response = null; HttpStatusCode statusCode = HttpPost(baseUri, smugUserAgent, postBody, out response); if (statusCode == HttpStatusCode.OK) { Match match = imageIdRegex.Match(response); if (match.Success) { string imageIdString = match.Groups[1].Captures[0].Value; int imageId = int.Parse(imageIdString); return imageId; } else { Console.WriteLine("Could not parse imageId from SmugMug response for photo {0} in album {1}", photo.photoId, currentAlbum.albumId); Console.WriteLine("Response from SmugMug was {0}", response); return 0; } } else { Console.WriteLine("Failed to upload photo {0} in album {1}", photo.photoId, currentAlbum.albumId); Console.WriteLine("Response from server was {0}", statusCode); } return 0; */ }