/// <summary> /// レシピ手順インスタンス作成 /// </summary> /// <param name="number">番号</param> /// <param name="photoFilePath">写真ファイルパス</param> /// <param name="text">手順テキスト</param> /// <returns>レシピ手順インスタンス</returns> public override IRecipeStep CreateStepInstance(int number, string photoFilePath, string text) { var step = new CookpadRecipeStep(this.Settings, this.Logger); step.Number.Value = number; step.PhotoFilePath.Value = photoFilePath; step.StepText.Value = text; return(step); }
/// <summary> /// レシピダウンロード /// </summary> /// <returns></returns> public override async Task DownloadRecipeAsync() { try { var htmlString = await this._httpClient.GetStringAsync(this.Url.Value); var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(htmlString); this.Title.Value = htmlDoc.QuerySelector("#recipe-title h1").InnerText.Trim(); using (var stream = await this._httpClient.GetStreamAsync(new Uri(htmlDoc.QuerySelector("#main-photo img").Attributes["data-large-photo"].Value))) using (var ms = new MemoryStream()) { stream.CopyTo(ms); this.Photo.Value = ms.ToArray(); } this.Description.Value = htmlDoc.QuerySelector("#description .description_text").InnerText.Trim(); this.Ingredients.Clear(); var category = ""; var ingredients = new List <CookpadRecipeIngredient>(); foreach (var ingredient in htmlDoc.QuerySelectorAll("#ingredients_list .ingredient_row")) { if (ingredient.QuerySelector(".ingredient_name") != null) { if (ingredient.ChildNodes.Any(x => x.HasClass("ingredient_category"))) { var categoryNode = ingredient.QuerySelector(".ingredient_category"); categoryNode.RemoveChild(categoryNode.QuerySelector("span")); category = categoryNode.InnerText.Trim(); continue; } var item = new CookpadRecipeIngredient(this); item.Id.Value = ingredients.Count + 1; // 自動採番 item.Category.Value = category; item.Name.Value = ingredient.QuerySelector(".ingredient_name").InnerText.Trim(); item.AmountText.Value = ingredient.QuerySelector(".ingredient_quantity").InnerText; ingredients.Add(item); } } this.Ingredients.AddRange(ingredients); this.Steps.Clear(); var steps = htmlDoc .QuerySelectorAll("#steps > [class^=step]") .Select(async(x, index) => { var cookpadRecipeStep = new CookpadRecipeStep(this.Settings, this.Logger); cookpadRecipeStep.Number.Value = index + 1; var photoUrl = x.QuerySelector(".image img")?.Attributes["data-large-photo"]?.Value; if (photoUrl != null) { using (var stream = await this._httpClient.GetStreamAsync(new Uri(photoUrl))) using (var ms = new MemoryStream()) { stream.CopyTo(ms); cookpadRecipeStep.Photo.Value = ms.ToArray(); } } cookpadRecipeStep.StepText.Value = x.QuerySelector(".step_text").InnerText.Trim(); return(cookpadRecipeStep); }); foreach (var step in steps) { this.Steps.Add(await step); } this.Author.Value = new CookpadRecipeAuthor { Name = htmlDoc.QuerySelector("#recipe_author_name").InnerText, Url = new Uri(this.Url.Value, htmlDoc.QuerySelector("#recipe_author_name").Attributes["href"].Value).AbsoluteUri }; this.Advice.Value = htmlDoc.QuerySelector("#advice")?.InnerText.Trim(); this.History.Value = htmlDoc.QuerySelector("#history")?.InnerText.Trim(); var yield = htmlDoc.QuerySelector("#ingredients .yield")?.InnerText.Trim(); if (yield != null) { yield = Regex.Replace(yield, @"^((.*))$", "$1"); } this.Yield.Value = yield; this.CookpadRecipeId.Value = Regex.Replace(htmlDoc.QuerySelector("#recipe_id_and_published_date .recipe_id").InnerText.Trim(), "^.+: ", ""); this.PublishedDate.Value = Regex.Replace(htmlDoc.QuerySelector("#published_date").InnerText.Trim(), "^.+: ", ""); this.UpdateDate.Value = Regex.Replace(htmlDoc.QuerySelector("#recipe_id_and_published_date span:not([class])").InnerText.Trim(), "^.+: ", ""); } catch (Exception ex) { this._failedNotification.OnNext((this, Behavior.Download, ex)); return; } this._completedNotification.OnNext((this, Behavior.Download)); }