| @@ -6,6 +6,7 @@ import 'package:webfeed/domain/rss_category.dart'; | |||
| import 'package:webfeed/domain/rss_cloud.dart'; | |||
| import 'package:webfeed/domain/rss_image.dart'; | |||
| import 'package:webfeed/domain/rss_item.dart'; | |||
| import 'package:webfeed/domain/syndication/syndication.dart'; | |||
| import 'package:webfeed/util/xml.dart'; | |||
| import 'package:xml/xml.dart'; | |||
| @@ -32,6 +33,7 @@ class RssFeed { | |||
| final int ttl; | |||
| final DublinCore dc; | |||
| final Itunes itunes; | |||
| final Syndication syndication; | |||
| RssFeed({ | |||
| this.title, | |||
| @@ -55,6 +57,7 @@ class RssFeed { | |||
| this.ttl, | |||
| this.dc, | |||
| this.itunes, | |||
| this.syndication, | |||
| }); | |||
| factory RssFeed.parse(String xmlString) { | |||
| @@ -105,6 +108,7 @@ class RssFeed { | |||
| ttl: int.tryParse(findFirstElement(channelElement, 'ttl')?.text ?? '0'), | |||
| dc: DublinCore.parse(channelElement), | |||
| itunes: Itunes.parse(channelElement), | |||
| syndication: Syndication.parse(channelElement), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,51 @@ | |||
| import 'package:webfeed/util/datetime.dart'; | |||
| import 'package:webfeed/util/xml.dart'; | |||
| import 'package:xml/xml.dart'; | |||
| enum SyndicationUpdatePeriod { hourly, daily, weekly, monthly, yearly } | |||
| class Syndication { | |||
| final SyndicationUpdatePeriod updatePeriod; | |||
| final int updateFrequency; | |||
| final DateTime updateBase; | |||
| Syndication({ | |||
| this.updatePeriod, | |||
| this.updateFrequency, | |||
| this.updateBase, | |||
| }); | |||
| factory Syndication.parse(XmlElement element) { | |||
| if (element == null) { | |||
| return null; | |||
| } | |||
| SyndicationUpdatePeriod updatePeriod; | |||
| switch (findFirstElement(element, 'sy:updatePeriod')?.text) { | |||
| case 'hourly': | |||
| updatePeriod = SyndicationUpdatePeriod.hourly; | |||
| break; | |||
| case 'daily': | |||
| updatePeriod = SyndicationUpdatePeriod.daily; | |||
| break; | |||
| case 'weekly': | |||
| updatePeriod = SyndicationUpdatePeriod.weekly; | |||
| break; | |||
| case 'monthly': | |||
| updatePeriod = SyndicationUpdatePeriod.monthly; | |||
| break; | |||
| case 'yearly': | |||
| updatePeriod = SyndicationUpdatePeriod.yearly; | |||
| break; | |||
| default: | |||
| updatePeriod = SyndicationUpdatePeriod.daily; | |||
| break; | |||
| } | |||
| return Syndication( | |||
| updatePeriod: updatePeriod, | |||
| updateFrequency: int.tryParse( | |||
| findFirstElement(element, 'sy:updateFrequency')?.text ?? '1'), | |||
| updateBase: | |||
| parseDateTime(findFirstElement(element, 'sy:updateBase')?.text), | |||
| ); | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import 'dart:io'; | |||
| import 'package:test/test.dart'; | |||
| import 'package:webfeed/domain/itunes/itunes_episode_type.dart'; | |||
| import 'package:webfeed/domain/itunes/itunes_type.dart'; | |||
| import 'package:webfeed/domain/syndication/syndication.dart'; | |||
| import 'package:webfeed/webfeed.dart'; | |||
| void main() { | |||
| @@ -385,4 +386,26 @@ void main() { | |||
| expect(feed.items.first.title, 'New Status Updates'); | |||
| expect(feed.items.first.link, 'http://www.mozilla.org/status/'); | |||
| }); | |||
| test('parse RSS-Syndication.xml', () { | |||
| var xmlString = File('test/xml/RSS-Syndication.xml').readAsStringSync(); | |||
| var feed = RssFeed.parse(xmlString); | |||
| expect(feed.title, 'Meerkat'); | |||
| expect(feed.link, 'http://meerkat.oreillynet.com'); | |||
| expect(feed.description, 'Meerkat: An Open Wire Service'); | |||
| expect(feed.image.title, 'Meerkat Powered!'); | |||
| expect(feed.image.url, | |||
| 'http://meerkat.oreillynet.com/icons/meerkat-powered.jpg'); | |||
| expect(feed.image.link, 'http://meerkat.oreillynet.com'); | |||
| expect(feed.syndication.updatePeriod, SyndicationUpdatePeriod.hourly); | |||
| expect(feed.syndication.updateFrequency, 2); | |||
| expect(feed.syndication.updateBase, DateTime.utc(2001, 1, 1, 12, 1)); | |||
| expect(feed.items.length, 1); | |||
| expect(feed.items.first.title, 'XML: A Disruptive Technology'); | |||
| expect(feed.items.first.description, | |||
| 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.'); | |||
| expect(feed.items.first.link, 'http://c.moreover.com/click/here.pl?r123'); | |||
| }); | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
| xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" | |||
| xmlns="http://purl.org/rss/1.0/"> | |||
| <channel rdf:about="http://meerkat.oreillynet.com/?_fl=rss1.0"> | |||
| <title>Meerkat</title> | |||
| <link>http://meerkat.oreillynet.com</link> | |||
| <description>Meerkat: An Open Wire Service</description> | |||
| <sy:updatePeriod>hourly</sy:updatePeriod> | |||
| <sy:updateFrequency>2</sy:updateFrequency> | |||
| <sy:updateBase>2001-01-01T12:01+00:00</sy:updateBase> | |||
| <image rdf:resource="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg"/> | |||
| </channel> | |||
| <image rdf:about="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg"> | |||
| <title>Meerkat Powered!</title> | |||
| <url>http://meerkat.oreillynet.com/icons/meerkat-powered.jpg</url> | |||
| <link>http://meerkat.oreillynet.com</link> | |||
| </image> | |||
| <item rdf:about="http://c.moreover.com/click/here.pl?r123"> | |||
| <title>XML: A Disruptive Technology</title> | |||
| <link>http://c.moreover.com/click/here.pl?r123</link> | |||
| <description>XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.</description> | |||
| </item> | |||
| </rdf:RDF> | |||