| @@ -6,6 +6,7 @@ import 'package:webfeed/domain/rss_category.dart'; | |||||
| import 'package:webfeed/domain/rss_cloud.dart'; | import 'package:webfeed/domain/rss_cloud.dart'; | ||||
| import 'package:webfeed/domain/rss_image.dart'; | import 'package:webfeed/domain/rss_image.dart'; | ||||
| import 'package:webfeed/domain/rss_item.dart'; | import 'package:webfeed/domain/rss_item.dart'; | ||||
| import 'package:webfeed/domain/syndication/syndication.dart'; | |||||
| import 'package:webfeed/util/xml.dart'; | import 'package:webfeed/util/xml.dart'; | ||||
| import 'package:xml/xml.dart'; | import 'package:xml/xml.dart'; | ||||
| @@ -32,6 +33,7 @@ class RssFeed { | |||||
| final int ttl; | final int ttl; | ||||
| final DublinCore dc; | final DublinCore dc; | ||||
| final Itunes itunes; | final Itunes itunes; | ||||
| final Syndication syndication; | |||||
| RssFeed({ | RssFeed({ | ||||
| this.title, | this.title, | ||||
| @@ -55,6 +57,7 @@ class RssFeed { | |||||
| this.ttl, | this.ttl, | ||||
| this.dc, | this.dc, | ||||
| this.itunes, | this.itunes, | ||||
| this.syndication, | |||||
| }); | }); | ||||
| factory RssFeed.parse(String xmlString) { | factory RssFeed.parse(String xmlString) { | ||||
| @@ -105,6 +108,7 @@ class RssFeed { | |||||
| ttl: int.tryParse(findFirstElement(channelElement, 'ttl')?.text ?? '0'), | ttl: int.tryParse(findFirstElement(channelElement, 'ttl')?.text ?? '0'), | ||||
| dc: DublinCore.parse(channelElement), | dc: DublinCore.parse(channelElement), | ||||
| itunes: Itunes.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:test/test.dart'; | ||||
| import 'package:webfeed/domain/itunes/itunes_episode_type.dart'; | import 'package:webfeed/domain/itunes/itunes_episode_type.dart'; | ||||
| import 'package:webfeed/domain/itunes/itunes_type.dart'; | import 'package:webfeed/domain/itunes/itunes_type.dart'; | ||||
| import 'package:webfeed/domain/syndication/syndication.dart'; | |||||
| import 'package:webfeed/webfeed.dart'; | import 'package:webfeed/webfeed.dart'; | ||||
| void main() { | void main() { | ||||
| @@ -385,4 +386,26 @@ void main() { | |||||
| expect(feed.items.first.title, 'New Status Updates'); | expect(feed.items.first.title, 'New Status Updates'); | ||||
| expect(feed.items.first.link, 'http://www.mozilla.org/status/'); | 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> | |||||