SFLink _mergeLinks(SFLink primary, SFLink secondary) { var p = primary; var s = secondary; if (p == null) { return(s); } if (s == null) { return(p); } if (p.MimeType != s.MimeType) { BasicMimeType mtye = p.MimeType.GetMostQualifiedMimeType(s.MimeType); return(p.MimeType == mtye ? p : s); } if (p.Rel != s.Rel) { return(p.Rel == SFRel.none ? s : p); } if (p.DiscoveredLink != s.DiscoveredLink) { return(p.DiscoveredLink ? s : p); } return(p); }
/// <summary> /// Sets Links based on the inputed ATOM xml. /// </summary> public void SetLinksFromXmlAtomEntry(XElement xEntry) { foreach (var xLink in xEntry.Elements("link")) { SFLink link = SFLink.AtomXmlLinkToLink(xLink); AddLink(link); } var contentSrcElem = xEntry .Elements("content") .FirstOrDefault(e => e.Attribute("src") != null); //.Where(e => e.Attribute("src") != null) //var contentSrcElem = xEntry.Element("content", "src"); if (contentSrcElem != null) { var cSrcLnk = SFLink.AtomXmlLinkToLink(contentSrcElem); if (cSrcLnk != null) { cSrcLnk.Rel = SFRel.src; AddLink(cSrcLnk); } } }
/// <summary> /// This prefers the first link that has a Rel type of either enclosure or src, /// AND whose LinkType is not IsNoneOrTextType, unless the predicate is sent in in which /// case that is used instead. If none have both, LinkType /// predominates then Rel, else null. /// </summary> public SFLink GetFirstEnclosure(Func <BasicMimeType, bool> linkType = null, bool returnFirstEnclosureIfNoLinkTypeMatches = false) { if (_Links.IsNulle()) { return(null); } SFLink encRel = null; if (linkType == null) { linkType = l => l.IsTextOrNone() == false; } foreach (SFLink l in _Links) { if (l != null) { if (linkType(l.MimeType)) { return(l); } if (l.Rel == SFRel.enclosure) { encRel = l; } } } return(returnFirstEnclosureIfNoLinkTypeMatches ? encRel : null); }
/// <summary> /// If the link url has a url.hostname that matches vimeo or youtube /// values, this sets the LinkType accordingly, and then returns true. /// Otherwise returns false. /// </summary> public bool AlterLink_VimeoYoutube(SFLink link) { // in the future could have a dictionary of all possible vimeo / youtube full hosts. // for the moment, if the host part has those in it's name we'll assume it is. // but we certainly could not do this with the full url value (e.g. someone could have 'vimeo' // in a url or blog title) if (link != null) { string linkHost = link.Uri.Host; if (linkHost.CountN() > 5) // && link.LinkType.IsAudio() == false) { { if (linkHost.Contains("vimeo")) { link.MimeType = BasicMimeType.video_vimeo; } else if (linkHost.Contains("youtu")) { link.MimeType = BasicMimeType.video_youtube; } else { return(false); } return(true); } } return(false); }
} = true; //SetYoutubeVimeoValues /// <summary> /// If you override this function, it is up to you to call /// <see cref="AlterLink_VimeoYoutube"/> if <see cref="SetYoutubeVimeoLinkMimeTypes"/> is true. /// </summary> public virtual SFLink AlterLink(SFLink link) { if (link == null || link.Url.IsNulle()) { return(null); } if (SetYoutubeVimeoLinkMimeTypes) { bool vimYtAltered = AlterLink_VimeoYoutube(link); } return(link); }
public SFHub(SFLink hubLink, SFLink selfLink = null) { if (hubLink.UrlN().IsNulle()) { throw new ArgumentNullException(); } HubLink = hubLink; if (selfLink.UrlN().NotNulle()) { SelfLink = selfLink; } }
public void AddMeta(XElement item) { var f = ParentSettings?.ParentFeed; if (item == null || f == null) { return; } // rawvoice // http://www.rawvoice.com/services/tools-and-resources/rawvoice-rss-2-0-module-xmlns-namespace-rss2/ /* metamark, if present as a sub-item of <item> and <item> includes an <enclosure> item, * specifies additional meta information that may complement the enclosure and/or may be used * during the playback of the enclosure’s media. It has four attributes: * type, link, position and duration and may contain a value. */ if (f.HasRawVoice) { foreach (var metaX in item.Elements(SimpleFeed.xname_rawvoice_metamark)) { var meta = new SFFeedMeta() { Source = "rawvoice.meta", Type = metaX.Attribute("type")?.Value?.Trim(), //.ValueN().TrimN(); Url = metaX.Attribute("link")?.Value?.Trim(), //.ValueN().TrimN(); Value = metaX?.Value?.Trim() }; if (meta.Value.NotNulle() || meta.Url.NotNulle()) { Metas.Add(meta); //BasicMimeType typ = isLinkRVMeta.V(meta.Type, BasicMimeType.none); string url = ExtraTextFuncs.IsWebLink(meta.Url) ? meta.Url : (ExtraTextFuncs.IsWebLink(meta.Value) ? meta.Value : null); if (url != null) { var lnk = new SFLink(url, meta.Type); if (lnk != null && lnk.IsValid) { AddLink(lnk); } } } } } }
/// <summary> /// Sets Links based on the inputed RSS xml. /// </summary> /// <param name="xEntry">RSS item.</param> public void SetLinksFromXmlRssItem(XElement xEntry) { if (xEntry != null) { XElement[] elems = xEntry.Elements().ToArray(); foreach (var xLink in elems.Where(e => e.Name == "link" || e.Name == "enclosure")) { SFLink link = SFLink.RssXmlLinkOrEnclosureToLink(xLink); AddLink(link); } foreach (var xLink in elems.Where(e => e.Name == SimpleFeed.xname_Atom_Link)) { SFLink link = SFLink.AtomXmlLinkToLink(xLink); AddLink(link); } foreach (var xLink in elems.Where(e => e.Name == SimpleFeed.xname_yahoomrss_content)) { SFLink link = SFLink.YahooMRSSXmlMediaElementToLink(xLink); AddLink(link); } } }
public void AddLink(SFLink link) { if (link.UrlN().NotNulle()) { if (ParentSettings != null && ParentSettings.AlterFeedLinks != null) { link = ParentSettings.AlterFeedLinks.AlterLink(link); } if (link.UrlN().NotNulle()) { if (Links.NotNulle()) { var lLink = Links.FirstN(lnk => lnk.Url.EqualsIgnoreCase(link.Url)); if (lLink != null) { link = _mergeLinks(link, lLink); } } Links.Add(link); } } }
public static string UrlN(this SFLink link) { return(link == null ? null : link.Url); }
public static SFLink YahooMRSSXmlMediaElementToLink(XElement xLink) { if (xLink == null) { return(null); } string _type = xLink.Attribute("type").ValueN().TrimN(); if (_type.IsNulle()) { _type = xLink.Attribute("medium").ValueN().TrimN(); //if(_type.NotNulle() && !_type.Contains("/")) // not needed, our type parser will handle this (I think) // _type = _type + "/null"; } string url = xLink.Attribute("url").ValueN().NullIfEmptyTrimmed(); if (url.IsNulle()) { return(null); } var lnk = new SFLink( url: url, mimeTypeStr: _type, length: xLink.Attribute("fileSize").ToInt( xLink.Attribute("duration").ToInt(0).Min(0)), // duration is the number of seconds the media object plays. It is an optional attribute. rel: null, title: null, isRssEncl: false, mimeType: BasicMimeType.audio // though the "Media RSS Spec" can be for pics or vids too, I doubt it's used much ever for that, presumption of audio is good one (I think) ); if (!lnk.IsValid) { return(null); } lnk.Height = xLink.Attribute("height").ToInt().Min(0); lnk.Width = xLink.Attribute("width").ToInt().Min(0); return(lnk); /* * <media:content * url: url="http://www.foo.com/movie.mov" * length: fileSize="12216320" * type: type="video/quicktime" * duration="185" * height="200" * width="300" * * // nada * medium="video" * isDefault="true" * expression="full" * bitrate="128" * framerate="25" * samplingrate="44.1" * channels="2" * lang="en" /> */ }
/// <summary> /// Gets first item of GetWebLinks (see notes there). /// </summary> public SFLink GetFirstWebLink_AlternateWins() { // OLD: //return _Links.NotNulle() // ? GetWebLinks().FirstOrDefault() // : null; if (_Links.IsNulle()) { return(null); } else { SFLink wLnk = null; int cnt = _Links.Count; for (int i = 0; i < cnt; i++) // (SFLink lnk in _Links) { { SFLink lnk = _Links[i]; if (lnk != null && lnk.Rel.IsNotEnclosureOrSelf() && lnk.MimeType.IsWebPageOrNone()) { if (wLnk == null) { wLnk = lnk; } else { // #1 --- REL IS THE SAME --- if (lnk.Rel == wLnk.Rel) { // If this link's mime is explicitly text_html and the other was not, it wins if (lnk.MimeType != wLnk.MimeType && lnk.MimeType == BasicMimeType.text_html) { wLnk = lnk; } else { continue; } } // #2 --- REL is NOT the same --- else { // a) IF last wLnk is alternate, and this one is not, last one wins, continue if (wLnk.Rel == SFRel.alternate) { continue; } // b) If this lnk IS alternate, then last wasn't (see above), so this one wins else if (lnk.Rel == SFRel.alternate) { wLnk = lnk; } // c) Neither rels are alternate, so look now compare mimes else if (lnk.MimeType != wLnk.MimeType && lnk.MimeType == BasicMimeType.text_html) { wLnk = lnk; // last could not be because above winnowed they aren't the same } else { continue; } } } if (wLnk.Rel == SFRel.alternate && wLnk.MimeType == BasicMimeType.text_html) { return(wLnk); } } } return(wLnk); } }