public async Task AddThemeToArticleAsync(ArticleModel article, string theme) { await Initialize(); await ExecuteSafe(async () => { var normalizedTheme = NormalizeThemeName(theme); var themeModel = ThemeManager.TryGetSimilarTheme(normalizedTheme); if (themeModel == null) { themeModel = new ThemeModel() { NormalizedName = normalizedTheme, Name = theme }; //concurrency: soem other thread may have added the same theme var tm = ThemeManager.TryAddTheme(themeModel); if (tm == themeModel) await _themeGenericRepository.AddAsync(themeModel); } if (article.Themes.Contains(themeModel)) return; article.Themes.Add(themeModel); await _sqliteService.Add(new ThemeArticleRelations() { ArticleId = article.GetId(), ThemeId = themeModel.GetId() }); }); }
public async void SelectArticle(ArticleModel am) { SetDisplayState(DisplayState.Article); Article = am; await _articleRepository.LoadFullArticleAsync(am); await _articleRepository.MarkArticleAsReadAsync(am); InitializeSpritz(); }
protected async Task AddThemesAsync(ArticleModel model, string[] themes = null) { if (model.GetId() == 0) return; if (themes != null) foreach (var theme in themes.Where(t => t != null)) { await _themeRepository.AddThemeToArticleAsync(model, theme); } await _themeRepository.AddThemeToArticleAsync(model, model.Feed.Name); }
public static async Task SaveArticle(ArticleModel model, ISqliteService service) { CleanUp(model); var articleGenericRepository = new GenericRepository<ArticleModel, ArticleEntity>(service); await articleGenericRepository.SaveAsyc(model); if (model.AfterSaveFunc != null) { var func = model.AfterSaveFunc; model.AfterSaveFunc = null; await func(); } }
public ArticleModel FeedToArticleModel(HtmlNode hn, FeedModel feed) { if (hn == null) return null; try { var a = new ArticleModel(); var linknode = hn.ChildNodes.Descendants("a").FirstOrDefault(); if (linknode != null) { a.PublicUri = linknode.GetAttributeValue("href", null); a.LogicUri = a.PublicUri; if (linknode.ChildNodes != null && linknode.ChildNodes.Any()) { var img = linknode.ChildNodes[0]; a.LeadImage = new ImageContentModel() { Url = img.GetAttributeValue("src", null) }; } } else { //newsticker return null; } var titlenode = hn.ChildNodes.FirstOrDefault(atr => atr.GetAttributeValue("title", null) != null); if (titlenode != null) a.Title = titlenode.GetAttributeValue("title", null); else return null; if (a.Title.Contains(":")) { a.SubTitle = a.Title.Substring(a.Title.IndexOf(":", StringComparison.Ordinal) + 1).Trim(); a.Title = a.Title.Substring(0, a.Title.IndexOf(":", StringComparison.Ordinal)); } a.DownloadDateTime = DateTime.Now; a.Author = "Chefredaktor"; return a; } catch (Exception ex) { LogHelper.Instance.Log(LogLevel.Error, "PostillonHelper.FeedToArticleModel failed", this, ex); return null; } }
public async Task AddRelatedThemesArticlesAsync(ArticleModel article) { await Initialize(); await ExecuteSafe(async () => { var aId = article.GetId(); var relations = await _sqliteService.GetByCondition<ThemeArticleRelations>(a => a.ArticleId == aId, null, false, 0, 0); var ids = relations.Select(q => q.ThemeId); foreach (var source in ThemeManager.GetAllThemes().Where(d => ids.Any(id => id == d.GetId()))) { article.Themes.Add(source); } }); }
public void Download(ArticleModel model) { if (model.LeadImage != null && model.LeadImage.LoadingState == LoadingState.New && !PriorityImages.Contains(model.LeadImage)) Download(model.LeadImage, true); foreach (var baseContentModel in model.Content) { if (baseContentModel is ImageContentModel) { Download((ImageContentModel)baseContentModel); } else if (baseContentModel is GalleryContentModel) { foreach (var imageContentModel in ((GalleryContentModel)baseContentModel).Images) { Download(imageContentModel); } } } }
public bool WriteProperties(ref ArticleModel am, HtmlNode na) { if (na == null) return false; try { string html = na.InnerHtml; if (html.Contains("<table")) html = html.Substring(0, html.IndexOf("<table", StringComparison.Ordinal)) + html.Substring(html.IndexOf("</table>", StringComparison.Ordinal) + ("</table>").Length); if (html.Contains("<span style=\"font-size: x-small;\">")) html = html.Substring(0, html.IndexOf("<span style=\"font-size: x-small;\">", StringComparison.Ordinal)); html = "<html><body><p>" + html + "</p></body></html>"; HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); var str = doc.DocumentNode.InnerText.Trim(); str = str.Replace("\n\n", "</p><p>"); str = "<p>" + str + "</p>"; am.Content.Clear(); am.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce(am.Feed.Source.PublicBaseUrl).HtmlToParagraph(str) }); am.DownloadDateTime = DateTime.Now; return true; } catch (Exception ex) { LogHelper.Instance.Log(LogLevel.Error, "PostillonHelper.ArticleToArticleModel failed", this, ex); return false; } }
public static async Task SaveArticleLeadImage(ArticleModel model, ISqliteService service, bool skipCleaning = false) { var imageContentGenericRepository = new GenericRepository<ImageContentModel, ImageContentEntity>(service); List<ContentEntity> oldLeadImages = null; var articleId = model.GetId(); if (!skipCleaning) oldLeadImages = (await service.GetByCondition<ContentEntity>(e => e.ParentId == articleId && e.ContentType == (int)ContentType.LeadImage, null, false, 0, 0)).ToList(); if (model.LeadImage != null) { if (model.LeadImage.GetId() != 0) { var leadImageId = model.LeadImage.GetId(); var oldLeadImage = oldLeadImages?.FirstOrDefault(o => o.ContentId == leadImageId); if (oldLeadImage != null) oldLeadImages?.Remove(oldLeadImage); await imageContentGenericRepository.SaveAsyc(model.LeadImage); } else { await imageContentGenericRepository.SaveAsyc(model.LeadImage); var entity = new ContentEntity { ContentId = model.LeadImage.GetId(), ParentId = model.GetId(), Index = 0, ContentType = (int)ContentType.LeadImage }; await service.Add(entity); } } if (!skipCleaning) await service.DeleteAllById<ContentEntity>(oldLeadImages.Select(d => d.Id)); }
private async Task<bool> ArticleToArticleModel(SternArticle na, ArticleModel am) { am.Content.Clear(); var p = HtmlConverter.CreateOnce(am.Feed.Source.PublicBaseUrl).HtmlToParagraph(GetHtml(na.content)); if (p != null && p.Any()) am.Content.Add(new TextContentModel() { Content = p }); if (!am.Content.Any()) am.Content.Add(TextHelper.TextToTextModel("Öffnen Sie den Artikel in Ihrem Browser für mehr Informationen.")); if (na.head != null && na.head.credits != null) am.Author = na.head.credits.author; if (string.IsNullOrWhiteSpace(am.Author)) am.Author = am.Feed.Source.Name; am.Themes.Clear(); await AddThemesAsync(am); return true; }
private void SelectArticle(ArticleModel model) { SimpleIoc.Default.GetInstance<ArticlePageViewModel>().SelectArticle(model); _historyNavigationService.NavigateTo(PageKeys.Article.ToString()); }
private ArticleModel GetSampleArticle() { var avm = new ArticleModel { Title = "Auf der Suche nach der nächsten Systemkrise", SubTitle = "Liquidität an den Finanzmärkten", Teaser = "Die Börsen sind gepannt auf die Entwicklung der strukturellen Verbesserung des isländischen Mondscheinmaterials", Author = "Author Maximus", LoadingState = LoadingState.Loaded, DownloadDateTime = DateTime.Now, PublishDateTime = DateTime.Now, LogicUri = "http://bazonline.ch/schweiz/standard/freie-bahn-fuer-mobility-pricing/story/24892119", PublicUri = "http://bazonline.ch/schweiz/standard/freie-bahn-fuer-mobility-pricing/story/24892119" }; avm.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce("").HtmlToParagraph("<h1>Über diese App</h1>" + "<p> " + "Die App versucht sich bei jedem Start zu aktualisieren. Ist kein Internet vorhanden, werden die Artikel des letzten Downloads angezeigt. " + "<br /><br />" + "Die Zeit und das verwendete Datenvolumen, die die Aktualisierung benötigt, hängt stark von den selektierten Quellen ab. Geht die Aktualisierung zu langsam, können Sie sich überlegen, wieder einige Feeds abzuschalten. " + "<br /><br />" + "Die App ist gratis und wird es auch bleiben. Sie generiert keine direkten oder indirekten Einnahmen.</p>" + "<h1>FAQ</h1>" + "<p><b>Wie werden die Medien ausgewählt, die von dieser App unterstützt werden?</b></p>" + "<p>Aufgrund der Machbarkeit einer Implementation, sowie der Anzahl wahrscheinlich interessierter Leser. " + "Die Qualität der Nachrichten oder deren politische Ausrichtung ist nicht relevant, grundsätzlich wird versucht, ein möglichst breites Spektrum abzudecken. " + "Medien, deren Popularität jedoch unter Anderem durch Clickbaiting (ein Beispiel für Clickbaiting: \"10 skurrile Tipps für eine erfolgreiches Leben\") gesichert wird, werden jedoch bei der Auswahl gezielt benachteiligt." + "<p><b>Könntest du die Zeitung XY in die App einbinden?</b></p>" + "<p>Schreibe mir eine Email an [email protected]</p>" + "<p><b>Gibt es Nachrichtenportale, die wahrscheinlich nicht implementiert werden?</b></p>" + "<p><b>Watson:</b> Implementierung ist zurzeit zeitaufwendig, ausserdem betreibt watson ausgiebiges Clickbaiting</p>" + "<p><b>Für welche Nachrichtenportale ist eine Implementierung geplant?</b></p>" + "<p>Zeit online, Süddeutsche.de, Spiegel online sowie zwei Zeitungen aus der französischen Schweiz</p>" + "<h1>Über den Herausgeber</h1>" + "<p>Mein Name ist Florian Moser, ich bin ein Programmierer aus Allschwil, Schweiz. <br /><br />" + "Neben Apps entwickle ich auch Webseiten und Webapplikationen. Ein Kontaktformular und weitere Informationen über meine Projekte sind auf meiner Webseite zu finden.</p>" + "<p><b>Webseite:</b> florianalexandermoser.ch<br />" + "<b>E-Mail:</b> [email protected]</p>") }); return avm; }
public async Task<bool> MarkArticleAsReadAsync(ArticleModel am) { am.IsRead = true; return true; }
public async Task LoadArticleThemesAsync(ArticleModel am) { await Initialize(); await ExecuteSafe(async () => { var id = am.GetId(); var cm = await _sqliteService.GetByCondition<ThemeArticleRelations>(d => d.ArticleId == id, null, false, 0, 0); foreach (var entry in cm.ToArray()) { var theme = ThemeManager.GetAllThemes().FirstOrDefault(t => t.GetId() == entry.ThemeId); if (theme != null) { am.Themes.Add(theme); } } }); }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); if (article == null) return false; HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(article); HtmlNode articlenode = doc.DocumentNode .Descendants("div").FirstOrDefault(o => o.GetAttributeValue("class", null) != null && o.GetAttributeValue("class", null).Contains("post-body")); var dateNode = doc.DocumentNode.Descendants("div").FirstOrDefault(o => o.GetAttributeValue("class", null) == "date-header"); var span = dateNode?.Descendants("span").FirstOrDefault(); articleModel.PublishDateTime = ParseDateTime(span?.InnerText); articleModel.Themes.Clear(); await AddThemesAsync(articleModel, new[] { "Satire" }); if (articlenode != null) { if (WriteProperties(ref articleModel, articlenode)) return true; } else { //happens; sometimes server resonds with service not available (probably some sort of DDOS protection) articleModel.Content.Clear(); articleModel.Content.Add(TextHelper.TextToTextModel("Der Artikel konnte nicht heruntergeladen werden")); articleModel.DownloadDateTime = DateTime.Now; return true; } return false; }); }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); var head = XmlHelper.GetSingleNode(article, "body.head"); if (head == null) return false; var author = XmlHelper.GetSingleNode(head, "byline"); if (author != null) { articleModel.Author = author.Substring(("<byline>").Length, author.Length - ("<byline>").Length * 2 - 1); } if (string.IsNullOrWhiteSpace(articleModel.Author)) articleModel.Author = "Welt"; var body = XmlHelper.GetSingleNode(article, "body.content"); body = body.Replace("<hl2>", "<h2>"); body = body.Replace("</hl2>", "</h2>"); body = XmlHelper.RemoveNodes(body, "media", "block class=\"related-links\""); if (body.Contains("Roboter und künstliche Intelligenz können eine Viertelmillion neue Jobs in Deutschland schaffen, glauben ")) return false; body = body.Replace("<body.content>", ""); body = body.Replace("</body.content>", ""); articleModel.Content.Clear(); articleModel.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce(articleModel.Feed.Source.PublicBaseUrl).HtmlToParagraph(body) }); return true; }); }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); var doc = new HtmlDocument(); doc.LoadHtml(article); var articleColumn = doc.DocumentNode .Descendants("div") .FirstOrDefault(o => o.GetAttributeValue("id", null) != null && o.GetAttributeValue("id", null).Contains("js-article-column")); if (articleColumn == null) return false; var content = articleColumn.Descendants("p").Where(d => d.GetAttributeValue("class", null) != "obfuscated" && d.GetAttributeValue("class", null) != "einestages-forum-info").ToArray(); var encryptedContent = articleColumn.Descendants("p").Where(d => d.GetAttributeValue("class", null) == "obfuscated").ToArray(); if (string.IsNullOrEmpty(articleModel.Author)) { var authorBox = articleColumn.Descendants("div").Where(d => d.GetAttributeValue("class", null) == "asset-box asset-author-box"); var authorP = authorBox.FirstOrDefault()?.Descendants("p"); var author = authorP?.FirstOrDefault()?.Descendants("b").FirstOrDefault(); articleModel.Author = author?.InnerText; } articleModel.Content.Clear(); if (content != null && content.Any()) { var html = content.Aggregate("", (current, htmlNode) => current + htmlNode.OuterHtml); articleModel.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce(articleModel.Feed.Source.PublicBaseUrl).HtmlToParagraph(CleanHtml(html)) }); } if (encryptedContent != null && encryptedContent.Any()) { foreach (var htmlNode in encryptedContent) { htmlNode.InnerHtml = DecryptContent(htmlNode.InnerHtml); } var html = encryptedContent.Aggregate("", (current, htmlNode) => current + htmlNode.OuterHtml); articleModel.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce(articleModel.Feed.Source.PublicBaseUrl).HtmlToParagraph(CleanHtml(html)) }); } if (string.IsNullOrWhiteSpace(articleModel.Author)) articleModel.Author = "Spiegel"; return content?.Length > 0 || encryptedContent?.Length > 0; }); }
public ArticleModel GetInfoArticle() { var model = new ArticleModel() { Author = "Florian Moser", Title = "Info", SubTitle = "Informationen über diese App", Teaser = "OfflineMedia erlaubt das Lesen der öffentlichen Onlineausgabe von Zeitungen, auch wenn gerade kein Internet verfügbar ist.", DownloadDateTime = DateTime.Now, PublishDateTime = DateTime.Now, LoadingState = LoadingState.Loaded, PublicUri = "http://offlinemedia.florianalexandermoser.ch/" }; model.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce("").HtmlToParagraph("<h2>Was ist diese App?</h2>" + "<p>Mit dieser App können Sie die meisten Nachrichtenportale der Schweiz, sowie einige aus Deutschland lesen. " + "Die App ist gratis und wird es auch bleiben. Sie generiert keine direkten oder indirekten Einnahmen.</p>" + "<h2>Wie werden die Medien ausgewählt, die von dieser App unterstützt werden?</h2>" + "<p>Aufgrund der Machbarkeit einer Implementation, sowie der Anzahl wahrscheinlich interessierter Leser. " + "Die Qualität der Nachrichten oder deren politische Ausrichtung ist nicht relevant, grundsätzlich versuche ich, möglicht alle wichtigen Nachrichtenkanäle zu integrieren. " + "Medien, deren Popularität jedoch vor allem durch Clickbaiting (ein Beispiel für Clickbaiting: \"10 skurrile Tipps für eine erfolgreiches Leben\") gesichert wird, werde ich nicht implementieren." + "Kontaktieren Sie mich, falls Sie eine Zeitung integriert haben möchten. </p>" + "<h2>Gibt es Nachrichtenportale, die wahrscheinlich nicht implementiert werden?</h2>" + "<p><b>Watson:</b> Die Implementierung ist zeitaufwendig, zudem betreibt watson ausgiebiges Clickbaiting</p>" + "<h2>Für welche Nachrichtenportale ist eine Implementierung geplant?</h2>" + "<p>Süddeutsche.de ist geplant, konnte ich bis jetzt aber nicht umsetzen</p>" ) }); return model; }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); var rootObj = JsonConvert.DeserializeObject<ArticleRoot>(article); if (rootObj == null) { LogHelper.Instance.Log(LogLevel.Error, "BildHelper.EvaluateFeed failed: rootObj is null after deserialisation", this); return false; } //clear content articleModel.Content.Clear(); articleModel.Themes.Clear(); if (rootObj.text != null) { foreach (var text in rootObj.text) { if (text.__nodeType__ == "CDATA") { text.CDATA = Regex.Replace(text.CDATA, "<p><strong><em>PS: Sind Sie bei Facebook\\?([a-zäöüA-Z0-9/:?=_<>\\\\\"\\-! .])+<\\/em><\\/strong><\\/p>", ""); var p = HtmlConverter.CreateOnce(articleModel.Feed.Source.PublicBaseUrl).HtmlToParagraph(text.CDATA); if (p != null && p.Any()) articleModel.Content.Add(new TextContentModel() { Content = p }); } } articleModel.PublishDateTime = rootObj.pubDate != null ? DateTime.Parse(rootObj.pubDate) : DateTime.Now; articleModel.Author = string.IsNullOrEmpty(rootObj.author) ? "Bild" : rootObj.author; var theme = new List<string>(); if (rootObj.wtChannels.Keyboard1 != null) theme.Add(rootObj.wtChannels.Keyboard1); if (rootObj.wtChannels.Keyboard2 != null) theme.Add(rootObj.wtChannels.Keyboard2); if (rootObj.wtChannels.Keyboard3 != null) theme.Add(rootObj.wtChannels.Keyboard3); if (rootObj.wtChannels.Keyboard4 != null) theme.Add(rootObj.wtChannels.Keyboard4); if (rootObj.wtChannels.Keyboard5 != null) theme.Add(rootObj.wtChannels.Keyboard5); await AddThemesAsync(articleModel, theme.ToArray()); return true; } return false; }); }
public async Task LoadArticleThemesAsync(ArticleModel am) { }
public Task<bool> MarkArticleAsReadAsync(ArticleModel am) { return ExecuteSafe(async () => { am.IsRead = true; return await _articleGenericRepository.UpdateAsyc(am); }); }
public Task<bool> LoadFullArticleAsync(ArticleModel am) { return ExecuteSafe(async () => { _imageDownloadService.Download(am); if (am.LoadingState == LoadingState.Loaded) { if (am.Content.Any()) return true; var id = am.GetId(); var contents = await _sqliteService.GetByCondition<ContentEntity>(s => s.ParentId == id, s => s.Index, false, 0, 0); for (int index = 0; index < contents.Count; index++) { if (am.Content.Count > index && am.Content[index].GetId() == contents[index].ContentId) continue; var contentEntity = contents[index]; switch (contentEntity.ContentType) { case (int)ContentType.Text: { var text = await _textContentGenericRepository.GetByIdAsync(contentEntity.ContentId); text.Content = text.ContentJson != null ? JsonConvert.DeserializeObject<ObservableCollection<ParagraphModel>>( text.ContentJson) : new ObservableCollection<ParagraphModel>(); am.Content.Add(text); break; } case (int)ContentType.Image: { var image = await _imageContentGenericRepository.GetByIdAsync(contentEntity.ContentId); am.Content.Add(image); break; } case (int)ContentType.Gallery: { var amId = am.GetId(); var galleryContents = await _sqliteService.GetByCondition<ContentEntity>(s => s.ParentId == amId, s => s.Index, false, 0, 0); var gallery = await _galleryContentGenericRepository.GetByIdAsync(contentEntity.ContentId); am.Content.Add(gallery); foreach ( var galleryContent in galleryContents.Where(g => g.ContentType == (int)ContentType.Image)) { var image = await _imageContentGenericRepository.GetByIdAsync(galleryContent.ContentId); gallery.Images.Add(image); } break; } } } await _themeRepository.LoadArticleThemesAsync(am); } else if (am.LoadingState == LoadingState.New) { if (await _permissionsService.CanDownloadArticles()) await ActualizeArticleAsync(am); } return true; }); }
public async Task<bool> WriteProperties(articlefeeditem[] na, ArticleModel am) { if (na == null) return false; articlefeeditem category = na.FirstOrDefault(a => a.type == "metadata"); if (category != null) { am.Themes.Clear(); await AddThemesAsync(am, new[] { category.section }); var auth = category.author as string; if (auth != null) am.Author = auth; } if (string.IsNullOrWhiteSpace(am.Author)) am.Author = am.Feed.Source.Name; articlefeeditem body = na.FirstOrDefault(a => a.type == "body"); //clear content am.Content.Clear(); if (body != null) { var htmlbody = body.items.Where(b => b.type == "text").ToList(); var unsupportedWarned = false; for (var i = 0; i < htmlbody.Count(); i++) { if (htmlbody[i].txt.StartsWith("<div class=\"full-block sponsorArticle author\">")) { var sponsorDiv = "<div class=\"sponsor_name\">"; var start = htmlbody[i].txt.Substring(htmlbody[i].txt.IndexOf(sponsorDiv, StringComparison.Ordinal) + sponsorDiv.Length); start = start.Substring(0, start.IndexOf("</div>", StringComparison.Ordinal)); am.Content.Add(TextHelper.TextToTextModel("Ein Beitrag von " + start)); } else if (htmlbody[i].txt.StartsWith("<div class='htmlInclude'>")) { if (htmlbody[i].txt == "<div class='htmlInclude'></div>") //empty special content, god knows why continue; if (!unsupportedWarned) { am.Content.Add(TextHelper.TextToTextModel( "Dieser Artikel enthält an dieser Stelle Inhalt der nicht unterstützt wird. Sehen Sie sich den Artikel im Web am, um alles anzuzeigen")); unsupportedWarned = true; } } else { var p = HtmlConverter.CreateOnce(am.Feed.Source.PublicBaseUrl).HtmlToParagraph(htmlbody[i].txt); if (p != null && p.Count > 0) am.Content.Add(new TextContentModel() { Content = p }); else { "ha".ToString(); } } } } if (!am.Content.Any()) { am.Content.Add(TextHelper.TextToTextModel( "Dieser Artikel enthält Inhalt der nicht unterstützt wird. Sehen Sie sich den Artikel im Web am, um alles anzuzeigen")); } articlefeeditem headline = na.FirstOrDefault(a => a.type == "headline"); if (headline != null && headline.author != null && headline.author.GetType() == typeof(articlefeeditem)) { articlefeeditem author = headline.author as articlefeeditem; if (author != null) am.Author = author.firstName; } return true; }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); var a = JsonConvert.DeserializeObject<articlefeeditem[]>(article); return await WriteProperties(a, articleModel); }); }
public override Task<bool> EvaluateArticle(ArticleModel articleModel) { return ExecuteSafe(async () => { var article = await DownloadAsync(articleModel); article = article.Replace("[[]]", "[]"); NzzArticle a = null; try { a = JsonConvert.DeserializeObject<NzzArticle>(article); } catch (Exception) { article = article.Replace(",\"publicationDateTime\":\"Invalid date\"", ""); try { a = JsonConvert.DeserializeObject<NzzArticle>(article); } catch { // no more fail safes } } if (a != null) return await ArticleToArticleModel(a, articleModel); return false; }); }
public async Task AddRelatedThemesArticlesAsync(ArticleModel article) { }
private Task<bool> ArticleToArticleModel(NzzArticle na, ArticleModel am) { return ExecuteSafe(async () => { am.Content.Clear(); for (int i = 0; i < na.body.Length; i++) { if (na.body[i].style == "h4") na.body[i].style = "h2"; if (na.body[i].style == "h3") na.body[i].style = "h1"; string starttag = "<" + na.body[i].style + ">"; string endtag = "</" + na.body[i].style + ">"; if (string.IsNullOrWhiteSpace(na.body[i].text)) { foreach (var nzzBox in na.body[i].boxes) { if (nzzBox.type == "image") { var uri = ParseImageUri(nzzBox.path); if (uri != null) am.Content.Add(new ImageContentModel() { Url = uri, Text = TextHelper.TextToTextModel(nzzBox.caption) }); } else if (nzzBox.type == "video" || nzzBox.type == "html") { //dont do shit } else if (nzzBox.type == "infobox") { var newContent = HtmlConverter.CreateOnce(am.Feed.Source.PublicBaseUrl).HtmlToParagraph("<p>" + nzzBox.body + "</p>"); foreach (var paragraphModel in newContent) { var ntm = new TextModel() { Children = paragraphModel.Children, TextType = TextType.Cursive }; paragraphModel.Children = new List<TextModel> { ntm }; } if (!string.IsNullOrWhiteSpace(nzzBox.title)) newContent.Insert(0, new ParagraphModel() { ParagraphType = ParagraphType.Title, Children = new List<TextModel>() { new TextModel() { Text = nzzBox.title, TextType = TextType.Cursive } } }); if (newContent.Any()) am.Content.Add(new TextContentModel() { Content = newContent }); } else LogHelper.Instance.LogInfo("nzz content type not found: " + nzzBox.mimeType, this); } } else { if (!na.body[i].text.StartsWith("Mehr zum Thema")) { var content = HtmlConverter.CreateOnce(am.Feed.Source.PublicBaseUrl).HtmlToParagraph(starttag + na.body[i].text + endtag); if (content != null && content.Count > 0) am.Content.Add(new TextContentModel() { Content = content }); } } } if (!am.Content.Any()) am.Content.Add(TextHelper.TextToTextModel("Der Inhalt dieses Artikels wird nicht unterstützt. Öffne den Artikel im Browser um mehr zu sehen.")); if (na.authors != null) foreach (var nzzAuthor in na.authors) { if (!string.IsNullOrEmpty(nzzAuthor.name)) { am.Author = nzzAuthor.name; if (!string.IsNullOrEmpty(nzzAuthor.abbreviation)) am.Author += ", " + nzzAuthor.abbreviation; } else am.Author = nzzAuthor.abbreviation; } if (!string.IsNullOrEmpty(na.agency)) am.Author += " " + na.agency; if (string.IsNullOrWhiteSpace(am.Author)) am.Author = "NZZ"; if (!string.IsNullOrEmpty(na.leadText)) am.Teaser = na.leadText; am.Themes.Clear(); await AddThemesAsync(am, na.departments); return true; }); }
public async Task<bool> LoadFullArticleAsync(ArticleModel am) { am.Content.Add(new TextContentModel() { Content = HtmlConverter.CreateOnce("").HtmlToParagraph("<h1>This is a sample Article Content</h1>" + "<p>A paragraph which explains more or less interesting stuff.</p>") }); return true; }
public Task<bool> SetArticleFavoriteStateAsync(ArticleModel am, bool isFavorite) { return ExecuteSafe(async () => { am.IsFavorite = isFavorite; return await _articleGenericRepository.UpdateAsyc(am); }); }
public async Task AddThemeToArticleAsync(ArticleModel article, string theme) { }