Support Syndication Support Rss Optional Elements#25625
Support Syndication Support Rss Optional Elements#25625shmao wants to merge 9 commits intodotnet:masterfrom
Conversation
Ref #25608.
| using (XmlReader reader = documentationElement.GetReader()) | ||
| { | ||
| SyndicationLink documentation = new Rss20FeedFormatter().ReadAlternateLink(reader, BaseUri); | ||
| return documentation; |
There was a problem hiding this comment.
ReadAlternateLink uses a UriParser which is why you need to instantiate an instance of Rss20FeedFormatter. This is just going to use the default Uri parser so we lose the benefit of the extensibility here. We should make ReadAlternateLink be a static method which takes a Uri parser as a parameter . Then do one of two things. 1) Have the class which instantiates the SyndicationFeed class set the parser in SyndicationFeed so any custom parser can be passed to ReadAlternateLink. 2) Pass the default Uri parser to ReadAlternateLink as that's what's being used here anyway.
There was a problem hiding this comment.
Sounds good. I went with option 2).
| xmlw.Close(); | ||
| using (XmlWriter xmlw = XmlWriter.Create(path)) | ||
| { | ||
| Rss20FeedFormatter atomFeed = new Rss20FeedFormatter(sf); |
There was a problem hiding this comment.
This seems oddly written. An instance of Rss20FeedFormatter is called atomFeed when we have an atom formatter?
There was a problem hiding this comment.
Good catch. The naming error was there before I changed this. Here I'm fixing the usage of the Close() method which was not called when exception happened in WriteTo.
I'll fix the names.
| Rss20FeedFormatter atomFeed = new Rss20FeedFormatter(sf); | ||
| atomFeed.WriteTo(xmlw); | ||
| } | ||
|
|
There was a problem hiding this comment.
There's no verification that we round trip all data?
There was a problem hiding this comment.
Yeah, I noticed this problem. But this is not a new added test. I'm fixing the usage of Close here.
| <!-- | ||
| <image> | ||
| <url>http://2.bp.blogspot.com/-NA5Jb-64eUg/URx8CSdcj_I/AAAAAAAAAUo/eCx0irI0rq0/s1600/bg_Contoso_logo3-20120824073001907469-620x349.jpg</url> | ||
| <title>The title is not the same to the original one</title> |
There was a problem hiding this comment.
This is commented out XML but this is a very real URL to a real image. Do we want to remove this or sanitize the values?
There was a problem hiding this comment.
There's a bug with the original implementation of reading <image>, which read different values and failed the tests. I'm commenting out this section out for now. We will need to revisit this when we add support for <image>.
| public partial class SyndicationFeed | ||
| { | ||
| public SyndicationLink Documentation { get{ throw null; } set{ } } | ||
| } |
There was a problem hiding this comment.
Has this been through API review? If not, we should close the PR until it's been vetted.
There was a problem hiding this comment.
This has not been approved yet. I added the NO MERGE label on the PR for now. I'd like to get feedback from others and see if it's even possible or make sense to add the new APIs before sending out API request..
| if (Feed.GetDocumentation() != null) | ||
| { | ||
| writer.WriteElementString(Rss20Constants.DocumentationTag, Feed.GetDocumentation().Uri.ToString()); | ||
| } |
| } | ||
|
|
||
| internal SyndicationLink GetDocumentation() | ||
| { |
There was a problem hiding this comment.
This is basically a property getter. Can you change this to a read only property with a name such as InternalDocumentation.
|
Just the one small issue (method -> property), otherwise LGTM. |
| // NOTE: This class implements Clone so if you add any members, please update the copy ctor | ||
| public class SyndicationFeed : IExtensibleSyndicationObject | ||
| { | ||
| private readonly static List<string> s_acceptedDays = new List<string> { "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" }; |
There was a problem hiding this comment.
Nit: static readonly (static before readonly)
| set { _title = value; } | ||
| } | ||
|
|
||
| internal SyndicationLink InternalDocumentation |
There was a problem hiding this comment.
Nit: Could be simplified as:
internal SyndicationLink InternalDocumentation => _documentation;| } | ||
| } | ||
|
|
||
| internal int? InternalTimeToLive |
There was a problem hiding this comment.
Nit: Could be simplified as:
internal int? InternalTimeToLive => _timeToLive;| } | ||
| } | ||
|
|
||
| internal Collection<int> InternalSkipHours |
There was a problem hiding this comment.
Nit: Could be simplified as:
internal int? InternalTimeToLive => _skipHours;| } | ||
| } | ||
|
|
||
| internal Collection<string> InternalSkipDays |
There was a problem hiding this comment.
Nit: Could be simplified as:
internal int? InternalTimeToLive => _skipDays;|
|
||
| if (hour < 0 || hour > 23) | ||
| { | ||
| throw new ArgumentException("The hour can't be lower than 0 or greater than 23."); |
There was a problem hiding this comment.
String should be added to the resources.
| return isValidTextInput(textInput) ? textInput : null; | ||
| } | ||
|
|
||
| private bool isValidTextInput(SyndicationTextInput textInput) |
There was a problem hiding this comment.
isValidTextInput => IsValidTextInput and can be static.
| case Rss20Constants.DocumentationTag: | ||
| if (InternalDocumentation != null) | ||
| { | ||
| return true; |
There was a problem hiding this comment.
These can be simplified, e.g.:
switch (localName)
{
case Rss20Constants.DocumentationTag:
return InternalDocumentation != null;
case Rss20Constants.TimeToLiveTag:
return InternalTimeToLive != null;
case Rss20Constants.TextInputTag:
return InternalTextInput != null;
// etc.
}|
|
||
| break; | ||
|
|
||
| default: |
There was a problem hiding this comment.
The default case isn't necessary
| private SyndicationLink TryReadDocumentationFromExtension(SyndicationElementExtensionCollection elementExtensions) | ||
| { | ||
| SyndicationElementExtension documentationElement = elementExtensions | ||
| .Where((e) => e.OuterName == Rss20Constants.DocumentationTag && e.OuterNamespace == Rss20Constants.Rss20Namespace) |
There was a problem hiding this comment.
Nit: (e) => ... can be simply e => .... Applies throughout.
| _timeToLive = TryReadTimeToLiveFromExtension(ElementExtensions); | ||
| } | ||
|
|
||
| return _timeToLive.Value; |
There was a problem hiding this comment.
Is InvalidOperationException if TryReadTimeToLiveFromExtension returns null appropriate?
There was a problem hiding this comment.
Good catch. I changed the type of the property to int?. Thanks.
|
The proposed APIs have not been reviewed yet. See https://github.com/dotnet/corefx/issues/25718. I will be out of office and be back on Jan 2, 2018. I'm leaving the PR open for now. If the the APIs are approved, please feel free to merge the PR. If anyone feels the PR being open for too long, please feel free to close it. Thanks. |
|
@dotnet-bot test OSX x64 Debug Build |
|
Closing, it's replaced by PR #26612 |
I'm prototyping supporting RSS optional elements using the
<docs>element. Please let me know if you have any concerns or suggestions. I'll apply this to other optional elements after this PR.The change enable users to read/wring
<docs>viaSyndicationFeed.Documentation. Here's a couple of things worth to note:<docs>viaSyndicationFeed.ElementExtensionswould still work after the change.SyndicationFeed.Documentationis ever used and becomes not null,SyndicationFeedFormatter.WriteTowould write<docs>with the value ofSyndicationFeed.Documentationand ignore the corresponding ElementExtension.Ref #25608.