public void IndexAsync(string t, string y, string l)
        {
            AsyncManager.OutstandingOperations.Increment();
            if (string.IsNullOrEmpty(t))
            {
                // error
                AsyncManager.Parameters["result"] = null;
                AsyncManager.OutstandingOperations.Decrement(); 
                return;
            }

            string imdbUrl;
            if (string.IsNullOrEmpty(y))
            {
                imdbUrl = string.Format("http://imdbapi.com/?t={0}&plot=full", t);
            }
            else
            {
                imdbUrl = string.Format("http://imdbapi.com/?t={0}&y={1}&plot=full", t, y);
            }

            var httpClient = new HttpClient();
            var imdbTask = httpClient.GetAsync(imdbUrl);

            var info = new MovieInfo();
            var detailsTask = imdbTask.ContinueWith(task => ProcessIMDbResult(task, info, l));
            detailsTask.ContinueWith(task =>
                {
                    AsyncManager.Parameters["result"] = info;
                    AsyncManager.OutstandingOperations.Decrement();
                });
        }
        public static IEnumerator<Task> CreateTranslatorRequestIterator(string language, MovieInfo movieInfo)
        {
            if (string.IsNullOrEmpty(language))
            {
                var tcs = new TaskCompletionSource<MovieInfo>();
                tcs.SetResult(movieInfo);
                yield return tcs.Task;
                yield break;
            }
            else
            {
                var tasks = new List<Task>();
                if (!string.IsNullOrEmpty(movieInfo.Plot))
                {
                    tasks.Add(
                        ProcessBingIterator(movieInfo.Plot, language).Run<string>().ContinueWith(task1 =>
                        {
                            movieInfo.Plot = task1.Result;
                        }));
                }
                if (movieInfo.NYTimesReviews != null)
                {
                    foreach (var review in movieInfo.NYTimesReviews)
                    {
                        if (!string.IsNullOrEmpty(review.Summary))
                        {
                            tasks.Add(ProcessBingIterator(review.Summary, language).Run<string>().ContinueWith(task =>
                            {
                                review.Summary = task.Result;
                            }));
                        }

                        if (!string.IsNullOrEmpty(review.Review))
                        {
                            tasks.Add(ProcessBingIterator(review.Review, language).Run<string>().ContinueWith(task =>
                            {
                                review.Review = task.Result;
                            }));
                        }
                    }
                }
                var taskWhenAll = TaskUtils.WhenAll(tasks.ToArray());
                yield return taskWhenAll;

                var tcs3 = new TaskCompletionSource<MovieInfo>();
                tcs3.SetResult(movieInfo);
                yield return tcs3.Task;
            }

        }
        public MovieInfo(MovieInfo other)
        {
            this.Title = other.Title;
            this.Year = other.Year;
            this.Director = other.Director;
            this.Plot = other.Plot;
            this.CoverUrl = other.CoverUrl;

            // no need to copy photo links
            this.FlickrPhotos = other.FlickrPhotos;

            // copy reviews
            if (other.NYTimesReviews != null)
            {
                this.NYTimesReviews = new List<MovieReview>();
                foreach (var review in other.NYTimesReviews)
                {
                    this.NYTimesReviews.Add(new MovieReview(review));
                }
            }
        }
        public static IEnumerator<Task> CreateMovieRequestIterator(string imdbUrl)
        {
            var httpClient = new HttpClient();
            var imdbTask = httpClient.GetAsync(imdbUrl);
            yield return imdbTask;

            if (!imdbTask.Result.IsSuccessStatusCode)
            {
                var tcs2 = new TaskCompletionSource<MovieInfo>();
                tcs2.SetResult(null);
                yield return tcs2.Task;
                yield break;
            }

            var taskReadImdbObject = imdbTask.Result.Content.ReadAsStreamAsync();
            yield return taskReadImdbObject;

            JavaScriptSerializer jsonMaster = new JavaScriptSerializer();
            IMDbObj imdbObj = jsonMaster.Deserialize<IMDbObj>(new StreamReader(taskReadImdbObject.Result).ReadToEnd());

            var info = new MovieInfo()
            {
                Title = imdbObj.Title,
                Year = imdbObj.Year,
                Director = imdbObj.Director,
                CoverUrl = imdbObj.Poster,
                Plot = imdbObj.Plot
            };

            var taskWhenAll = TaskUtils.WhenAll(
                CreateFlickrTask(imdbObj, info),
                CreateNYTimesTask(imdbObj, info)
            );
            yield return taskWhenAll;

            var tcs3 = new TaskCompletionSource<MovieInfo>();
            tcs3.SetResult(info);
            yield return tcs3.Task;
        }
        public void ProcessIMDbResult(Task<HttpResponseMessage> task, MovieInfo info, string l)
        {
            IMDbObj imdbObj = null;
            if (task.Result.IsSuccessStatusCode)
            {
                // TODO error handling

                JavaScriptSerializer jsonMaster = new JavaScriptSerializer();
                // TODO?
                var task2 = task.Result.Content.ReadAsStreamAsync();
                imdbObj = jsonMaster.Deserialize<IMDbObj>(new StreamReader(task2.Result).ReadToEnd());
            }

            info.Title = imdbObj.Title;
            info.Year = imdbObj.Year;
            info.Director = imdbObj.Director;
            info.CoverUrl = imdbObj.Poster;

            var httpClient = new HttpClient();
            var flickrUrl = string.Format("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={0}&format=json&nojsoncallback=1&text={1}+{2}&sort=interestingness-desc",
                _flickrKey, imdbObj.Title, imdbObj.Director);
            var taskFlickr = httpClient.GetAsync(flickrUrl);
            taskFlickr.ContinueWith(ProcessFlickrResult, TaskContinuationOptions.AttachedToParent);

            var year = Convert.ToInt32(imdbObj.Year);
            var nyTimesUrl = string.Format("http://api.nytimes.com/svc/movies/v2/reviews/search.json?query={0}&api-key={1}&opening-date={2}-01-01;{3}-12-31",
                imdbObj.Title, _nyTimesKey, year, year + 1);
            var taskNYTimes = httpClient.GetAsync(nyTimesUrl);
            taskNYTimes.ContinueWith(ProcessNYTimesResult, TaskContinuationOptions.AttachedToParent);

            if (!string.IsNullOrEmpty(l))
            {
                var bingUrl = string.Format("http://api.bing.net/json.aspx?AppId={0}&Query={PLOT|CAPSULE-REVIEW}&Sources=Translation&Version=2.2&Translation.SourceLanguage=en&Translation.TargetLanguage={1}",
                    _bingKey, l);
                var taskBing = httpClient.GetAsync(bingUrl);
                taskBing.ContinueWith(ProcessBingResult, TaskContinuationOptions.AttachedToParent);
            }
        }
 public ActionResult IndexCompleted(MovieInfo result)
 {
     return Json(result, JsonRequestBehavior.AllowGet);
 }
        private static Task CreateNYTimesTask(IMDbObj imdbObj, MovieInfo info)
        {
            var tcs = new TaskCompletionSource<MovieInfo>();
            var year = Convert.ToInt32(imdbObj.Year);
            var nyTimesUrl = string.Format("http://api.nytimes.com/svc/movies/v2/reviews/search.json?query={0}&api-key={1}&opening-date={2}-01-01;{3}-12-31",
                imdbObj.Title, _nyTimesKey, year, year + 1);
            var httpClient = new HttpClient();

            var requestTask = httpClient.GetAsync(nyTimesUrl);
            requestTask.ContinueWith(t1 =>
            {
                if (t1.Result.IsSuccessStatusCode)
                {
                    var taskReadObject = requestTask.Result.Content.ReadAsStreamAsync();
                    taskReadObject.ContinueWith(t2 =>
                    {
                        JavaScriptSerializer jsonMaster = new JavaScriptSerializer();
                        var nyTimesObj = jsonMaster.Deserialize<NYTimesObj>(new StreamReader(t2.Result).ReadToEnd());
                        if (nyTimesObj.num_results > 0)
                        {
                            info.NYTimesReviews = new List<MovieReview>();
                            foreach (var critic in nyTimesObj.results)
                            {
                                info.NYTimesReviews.Add(new MovieReview()
                                {
                                    Reviewer = critic.byline,
                                    Summary = critic.summary_short,
                                    Review = critic.capsule_review,
                                    Url = critic.link.url
                                });
                            }
                            tcs.SetResult(info);
                        }
                    });
                }
            });
            return tcs.Task;
        }
 private static Task CreateFlickrTask(IMDbObj imdbObj, MovieInfo info)
 {
     var tcs = new TaskCompletionSource<MovieInfo>();
     var httpClient = new HttpClient();
     var flickrUrl = string.Format("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={0}&format=json&nojsoncallback=1&text={1}+{2}&sort=interestingness-desc",
         _flickrKey, imdbObj.Title, imdbObj.Director);
     var taskFlickr = httpClient.GetAsync(flickrUrl);
     taskFlickr.ContinueWith(t =>
     {
         if (t.Result.IsSuccessStatusCode)
         {
             var taskReadFlickrObj = t.Result.Content.ReadAsStreamAsync();
             taskReadFlickrObj.ContinueWith(t2 =>
             {
                 JavaScriptSerializer jsonMaster = new JavaScriptSerializer();
                 var flickrInfo = jsonMaster.Deserialize<FlickrObj>(new StreamReader(t2.Result).ReadToEnd());
                 info.FlickrPhotos = flickrInfo.Photos.Photo.Select(p =>
                     string.Format("http://farm{0}.static.flickr.com/{1}/{2}_{3}.jpg",
                     p.Farm, p.Server, p.Id, p.Secret)).ToList();
                 tcs.SetResult(info);
             });
         }
     });
     return tcs.Task;
 }