Wito Chandra 7 лет назад
Родитель
Сommit
cd9415c0b2
7 измененных файлов: 188 добавлений и 118 удалений
  1. +61
    -0
      lib/domain/dublin_core/dublin_core.dart
  2. +8
    -5
      lib/domain/rss_cloud.dart
  3. +35
    -96
      lib/domain/rss_feed.dart
  4. +3
    -0
      lib/domain/rss_image.dart
  5. +6
    -17
      lib/domain/rss_item.dart
  6. +37
    -0
      test/rss_test.dart
  7. +38
    -0
      test/xml/RSS-DC.xml

+ 61
- 0
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,
);
}
}

+ 8
- 5
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");


+ 35
- 96
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<String>();
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<int>();
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
''';
}
}

+ 3
- 0
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);


+ 6
- 17
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
''';
}
}

+ 37
- 0
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");
});
}

+ 38
- 0
test/xml/RSS-DC.xml Просмотреть файл

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<dc:title>title</dc:title>
<dc:creator>creator</dc:creator>
<dc:subject>subject</dc:subject>
<dc:description>description</dc:description>
<dc:publisher>publisher</dc:publisher>
<dc:contributor>contributor</dc:contributor>
<dc:date>2000-01-01T12:00+00:00</dc:date>
<dc:type>type</dc:type>
<dc:format>format</dc:format>
<dc:identifier>identifier</dc:identifier>
<dc:source>source</dc:source>
<dc:language>language</dc:language>
<dc:relation>relation</dc:relation>
<dc:coverage>coverage</dc:coverage>
<dc:rights>rights</dc:rights>
<item>
<dc:title>title</dc:title>
<dc:creator>creator</dc:creator>
<dc:subject>subject</dc:subject>
<dc:description>description</dc:description>
<dc:publisher>publisher</dc:publisher>
<dc:contributor>contributor</dc:contributor>
<dc:date>2000-01-01T12:00+00:00</dc:date>
<dc:type>type</dc:type>
<dc:format>format</dc:format>
<dc:identifier>identifier</dc:identifier>
<dc:source>source</dc:source>
<dc:language>language</dc:language>
<dc:relation>relation</dc:relation>
<dc:coverage>coverage</dc:coverage>
<dc:rights>rights</dc:rights>
</item>
</channel>
</rss>

Загрузка…
Отмена
Сохранить