From cd9415c0b233d9b189fb061e90616210488bc10b Mon Sep 17 00:00:00 2001 From: Wito Chandra Date: Tue, 2 Oct 2018 20:03:06 +0700 Subject: [PATCH] add dublin core --- lib/domain/dublin_core/dublin_core.dart | 61 +++++++++++ lib/domain/rss_cloud.dart | 13 ++- lib/domain/rss_feed.dart | 131 +++++++----------------- lib/domain/rss_image.dart | 3 + lib/domain/rss_item.dart | 23 ++--- test/rss_test.dart | 37 +++++++ test/xml/RSS-DC.xml | 38 +++++++ 7 files changed, 188 insertions(+), 118 deletions(-) create mode 100644 lib/domain/dublin_core/dublin_core.dart create mode 100644 test/xml/RSS-DC.xml diff --git a/lib/domain/dublin_core/dublin_core.dart b/lib/domain/dublin_core/dublin_core.dart new file mode 100644 index 0000000..564bb4c --- /dev/null +++ b/lib/domain/dublin_core/dublin_core.dart @@ -0,0 +1,61 @@ +import 'package:webfeed/util/helpers.dart'; +import 'package:xml/xml.dart'; + +class DublinCore { + final String title; + final String description; + final String creator; + final String subject; + final String publisher; + final String contributor; + final String date; + final String type; + final String format; + final String identifier; + final String source; + final String language; + final String relation; + final String coverage; + final String rights; + + DublinCore({ + this.title, + this.description, + this.creator, + this.subject, + this.publisher, + this.contributor, + this.date, + this.type, + this.format, + this.identifier, + this.source, + this.language, + this.relation, + this.coverage, + this.rights, + }); + + factory DublinCore.parse(XmlElement element) { + if (element == null) { + return null; + } + return DublinCore( + title: findElementOrNull(element, "dc:title")?.text, + description: findElementOrNull(element, "dc:description")?.text, + creator: findElementOrNull(element, "dc:creator")?.text, + subject: findElementOrNull(element, "dc:subject")?.text, + publisher: findElementOrNull(element, "dc:publisher")?.text, + contributor: findElementOrNull(element, "dc:contributor")?.text, + date: findElementOrNull(element, "dc:date")?.text, + type: findElementOrNull(element, "dc:type")?.text, + format: findElementOrNull(element, "dc:format")?.text, + identifier: findElementOrNull(element, "dc:identifier")?.text, + source: findElementOrNull(element, "dc:source")?.text, + language: findElementOrNull(element, "dc:language")?.text, + relation: findElementOrNull(element, "dc:relation")?.text, + coverage: findElementOrNull(element, "dc:coverage")?.text, + rights: findElementOrNull(element, "dc:rights")?.text, + ); + } +} diff --git a/lib/domain/rss_cloud.dart b/lib/domain/rss_cloud.dart index 114541e..729d632 100644 --- a/lib/domain/rss_cloud.dart +++ b/lib/domain/rss_cloud.dart @@ -1,11 +1,11 @@ import 'package:xml/xml.dart'; class RssCloud { - String domain; - String port; - String path; - String registerProcedure; - String protocol; + final String domain; + final String port; + final String path; + final String registerProcedure; + final String protocol; RssCloud( this.domain, @@ -16,6 +16,9 @@ class RssCloud { ); factory RssCloud.parse(XmlElement node) { + if (node == null) { + return null; + } var domain = node.getAttribute("domain"); var port = node.getAttribute("port"); var path = node.getAttribute("path"); diff --git a/lib/domain/rss_feed.dart b/lib/domain/rss_feed.dart index 65445ee..85d4249 100644 --- a/lib/domain/rss_feed.dart +++ b/lib/domain/rss_feed.dart @@ -1,5 +1,6 @@ import 'dart:core'; +import 'package:webfeed/domain/dublin_core/dublin_core.dart'; import 'package:webfeed/domain/rss_category.dart'; import 'package:webfeed/domain/rss_cloud.dart'; import 'package:webfeed/domain/rss_image.dart'; @@ -27,6 +28,7 @@ class RssFeed { final String rating; final String webMaster; final int ttl; + final DublinCore dc; RssFeed({ this.title, @@ -47,6 +49,7 @@ class RssFeed { this.rating, this.webMaster, this.ttl, + this.dc, }); factory RssFeed.parse(String xmlString) { @@ -55,105 +58,41 @@ class RssFeed { try { channelElement = document.findAllElements("channel").first; } on StateError { - throw new ArgumentError("channel not found"); + throw ArgumentError("channel not found"); } - var title = xmlGetString(channelElement, "title", strict: false); - var description = - xmlGetString(channelElement, "description", strict: false); - var link = xmlGetString(channelElement, "link", strict: false); - var feeds = channelElement.findElements("item").map((element) { - return new RssItem.parse(element); - }).toList(); - - RssImage image; - try { - image = new RssImage.parse(channelElement.findElements("image").first); - } on StateError {} - - RssCloud cloud; - try { - cloud = new RssCloud.parse(channelElement.findElements("cloud").first); - } on StateError {} - - var categories = channelElement.findElements("category").map((element) { - return new RssCategory.parse(element); - }).toList(); - - var skipDays = new List(); - var skipDaysNodes = channelElement.findElements("skipDays"); - if (skipDaysNodes.isNotEmpty) { - skipDays = skipDaysNodes.first.findAllElements("day").map((element) { + return RssFeed( + title: findElementOrNull(channelElement, "title")?.text, + description: findElementOrNull(channelElement, "description")?.text, + link: findElementOrNull(channelElement, "link")?.text, + items: channelElement.findElements("item").map((element) { + return RssItem.parse(element); + }).toList(), + image: RssImage.parse(findElementOrNull(channelElement, "image")), + cloud: RssCloud.parse(findElementOrNull(channelElement, "cloud")), + categories: channelElement.findElements("category").map((element) { + return RssCategory.parse(element); + }).toList(), + skipDays: findElementOrNull(channelElement, "skipDays") + ?.findAllElements("day") + ?.map((element) { return element.text; - }).toList(); - } - var skipHours = new List(); - var skipHoursNodes = channelElement.findElements("skipHours"); - if (skipHoursNodes.isNotEmpty) { - skipHours = skipHoursNodes.first.findAllElements("hour").map((element) { - try { - return int.parse(element.text); - } on FormatException { - return null; - } - }).toList(); - } - - var lastBuildDate = - xmlGetString(channelElement, "lastBuildDate", strict: false); - var language = xmlGetString(channelElement, "language", strict: false); - var generator = xmlGetString(channelElement, "generator", strict: false); - var copyright = xmlGetString(channelElement, "copyright", strict: false); - var docs = xmlGetString(channelElement, "docs", strict: false); - var managingEditor = - xmlGetString(channelElement, "managingEditor", strict: false); - var rating = xmlGetString(channelElement, "rating", strict: false); - var webMaster = xmlGetString(channelElement, "webMaster", strict: false); - var ttl = xmlGetInt(channelElement, "ttl", strict: false); - - return new RssFeed( - title: title, - description: description, - link: link, - items: feeds, - image: image, - cloud: cloud, - categories: categories, - skipDays: skipDays, - skipHours: skipHours, - lastBuildDate: lastBuildDate, - language: language, - generator: generator, - copyright: copyright, - docs: docs, - managingEditor: managingEditor, - rating: rating, - webMaster: webMaster, - ttl: ttl, + })?.toList(), + skipHours: findElementOrNull(channelElement, "skipHours") + ?.findAllElements("hour") + ?.map((element) { + return int.tryParse(element.text ?? "0"); + })?.toList(), + lastBuildDate: findElementOrNull(channelElement, "lastBuildDate")?.text, + language: findElementOrNull(channelElement, "language")?.text, + generator: findElementOrNull(channelElement, "generator")?.text, + copyright: findElementOrNull(channelElement, "copyright")?.text, + docs: findElementOrNull(channelElement, "docs")?.text, + managingEditor: findElementOrNull(channelElement, "managingEditor")?.text, + rating: findElementOrNull(channelElement, "rating")?.text, + webMaster: findElementOrNull(channelElement, "webMaster")?.text, + ttl: int.tryParse(findElementOrNull(channelElement, "ttl")?.text ?? "0"), + dc: DublinCore.parse(channelElement), ); } - - @override - String toString() { - return ''' - title: $title - description: $description - link: $link - items: $items - image: $image - cloud: $cloud - categories: $categories - skipDays: $skipDays - skipHours: $skipHours - lastBuildDate: $lastBuildDate - language: $language - generator: $generator - copyright: $copyright - docs: $docs - managingEditor: $managingEditor - rating: $rating - webMaster: $webMaster - ttl: $ttl - '''; - } } diff --git a/lib/domain/rss_image.dart b/lib/domain/rss_image.dart index 9e758af..48dadce 100644 --- a/lib/domain/rss_image.dart +++ b/lib/domain/rss_image.dart @@ -9,6 +9,9 @@ class RssImage { RssImage(this.title, this.url, this.link); factory RssImage.parse(XmlElement element) { + if (element == null) { + return null; + } var title = xmlGetString(element, "title", strict: false); var url = xmlGetString(element, "url", strict: false); var link = xmlGetString(element, "link", strict: false); diff --git a/lib/domain/rss_item.dart b/lib/domain/rss_item.dart index 1bba41d..f290a96 100644 --- a/lib/domain/rss_item.dart +++ b/lib/domain/rss_item.dart @@ -1,3 +1,4 @@ +import 'package:webfeed/domain/dublin_core/dublin_core.dart'; import 'package:webfeed/domain/media/media.dart'; import 'package:webfeed/domain/rss_category.dart'; import 'package:webfeed/domain/rss_content.dart'; @@ -21,6 +22,7 @@ class RssItem { final RssContent content; final Media media; final RssEnclosure enclosure; + final DublinCore dc; RssItem({ this.title, @@ -35,15 +37,16 @@ class RssItem { this.content, this.media, this.enclosure, + this.dc, }); factory RssItem.parse(XmlElement element) { - return new RssItem( + return RssItem( title: findElementOrNull(element, "title")?.text, description: findElementOrNull(element, "description")?.text, link: findElementOrNull(element, "link")?.text, categories: element.findElements("category").map((element) { - return new RssCategory.parse(element); + return RssCategory.parse(element); }).toList(), guid: findElementOrNull(element, "guid")?.text, pubDate: findElementOrNull(element, "pubDate")?.text, @@ -53,21 +56,7 @@ class RssItem { content: RssContent.parse(findElementOrNull(element, "content:encoded")), media: Media.parse(element), enclosure: RssEnclosure.parse(findElementOrNull(element, "enclosure")), + dc: DublinCore.parse(element), ); } - - @override - String toString() { - return ''' - title: $title - description: $description - link: $link - guid: $guid - pubDate: $pubDate - author: $author - comments: $comments - source: $source - content: $content - '''; - } } diff --git a/test/rss_test.dart b/test/rss_test.dart index 16e2c98..d42752e 100644 --- a/test/rss_test.dart +++ b/test/rss_test.dart @@ -213,4 +213,41 @@ void main() { expect(item.media.scenes.first.startTime, "00:15"); expect(item.media.scenes.first.endTime, "00:45"); }); + test("parse RSS-DC.xml", (){ + var xmlString = File("test/xml/RSS-DC.xml").readAsStringSync(); + + var feed = RssFeed.parse(xmlString); + + expect(feed.dc.title, "title"); + expect(feed.dc.creator, "creator"); + expect(feed.dc.subject, "subject"); + expect(feed.dc.description, "description"); + expect(feed.dc.publisher, "publisher"); + expect(feed.dc.contributor, "contributor"); + expect(feed.dc.date, "2000-01-01T12:00+00:00"); + expect(feed.dc.type, "type"); + expect(feed.dc.format, "format"); + expect(feed.dc.identifier, "identifier"); + expect(feed.dc.source, "source"); + expect(feed.dc.language, "language"); + expect(feed.dc.relation, "relation"); + expect(feed.dc.coverage, "coverage"); + expect(feed.dc.rights, "rights"); + + expect(feed.items.first.dc.title, "title"); + expect(feed.items.first.dc.creator, "creator"); + expect(feed.items.first.dc.subject, "subject"); + expect(feed.items.first.dc.description, "description"); + expect(feed.items.first.dc.publisher, "publisher"); + expect(feed.items.first.dc.contributor, "contributor"); + expect(feed.items.first.dc.date, "2000-01-01T12:00+00:00"); + expect(feed.items.first.dc.type, "type"); + expect(feed.items.first.dc.format, "format"); + expect(feed.items.first.dc.identifier, "identifier"); + expect(feed.items.first.dc.source, "source"); + expect(feed.items.first.dc.language, "language"); + expect(feed.items.first.dc.relation, "relation"); + expect(feed.items.first.dc.coverage, "coverage"); + expect(feed.items.first.dc.rights, "rights"); + }); } diff --git a/test/xml/RSS-DC.xml b/test/xml/RSS-DC.xml new file mode 100644 index 0000000..6f1242d --- /dev/null +++ b/test/xml/RSS-DC.xml @@ -0,0 +1,38 @@ + + + + title + creator + subject + description + publisher + contributor + 2000-01-01T12:00+00:00 + type + format + identifier + source + language + relation + coverage + rights + + title + creator + subject + description + publisher + contributor + 2000-01-01T12:00+00:00 + type + format + identifier + source + language + relation + coverage + rights + + + \ No newline at end of file