Procházet zdrojové kódy

Merge pull request #1 from witochandra/master

merge 0.6.0
master
Xander Gottlieb před 6 roky
committed by GitHub
rodič
revize
040c026aea
V databázi nebyl nalezen žádný známý klíč pro tento podpis ID GPG klíče: 4AEE18F83AFDEB23
72 změnil soubory, kde provedl 1133 přidání a 950 odebrání
  1. +19
    -0
      .github/workflows/dart.yml
  2. +17
    -0
      CHANGELOG.md
  3. +6
    -4
      README.md
  4. +2
    -3
      analysis_options.yaml
  5. +11
    -16
      example/main.dart
  6. +3
    -3
      lib/domain/atom_category.dart
  7. +35
    -31
      lib/domain/atom_feed.dart
  8. +3
    -3
      lib/domain/atom_generator.dart
  9. +25
    -22
      lib/domain/atom_item.dart
  10. +7
    -7
      lib/domain/atom_link.dart
  11. +7
    -6
      lib/domain/atom_person.dart
  12. +11
    -7
      lib/domain/atom_source.dart
  13. +24
    -17
      lib/domain/dublin_core/dublin_core.dart
  14. +102
    -0
      lib/domain/itunes/itunes.dart
  15. +20
    -0
      lib/domain/itunes/itunes_category.dart
  16. +16
    -0
      lib/domain/itunes/itunes_episode_type.dart
  17. +14
    -0
      lib/domain/itunes/itunes_image.dart
  18. +17
    -0
      lib/domain/itunes/itunes_owner.dart
  19. +14
    -0
      lib/domain/itunes/itunes_type.dart
  20. +3
    -3
      lib/domain/media/category.dart
  21. +8
    -8
      lib/domain/media/community.dart
  22. +15
    -15
      lib/domain/media/content.dart
  23. +2
    -2
      lib/domain/media/copyright.dart
  24. +3
    -3
      lib/domain/media/credit.dart
  25. +2
    -2
      lib/domain/media/description.dart
  26. +6
    -6
      lib/domain/media/embed.dart
  27. +10
    -10
      lib/domain/media/group.dart
  28. +2
    -2
      lib/domain/media/hash.dart
  29. +3
    -3
      lib/domain/media/license.dart
  30. +52
    -52
      lib/domain/media/media.dart
  31. +2
    -2
      lib/domain/media/param.dart
  32. +3
    -3
      lib/domain/media/peer_link.dart
  33. +4
    -4
      lib/domain/media/player.dart
  34. +5
    -5
      lib/domain/media/price.dart
  35. +2
    -2
      lib/domain/media/rating.dart
  36. +3
    -3
      lib/domain/media/restriction.dart
  37. +2
    -2
      lib/domain/media/rights.dart
  38. +6
    -6
      lib/domain/media/scene.dart
  39. +5
    -5
      lib/domain/media/star_rating.dart
  40. +3
    -3
      lib/domain/media/statistics.dart
  41. +3
    -3
      lib/domain/media/status.dart
  42. +2
    -2
      lib/domain/media/tags.dart
  43. +5
    -5
      lib/domain/media/text.dart
  44. +5
    -5
      lib/domain/media/thumbnail.dart
  45. +2
    -2
      lib/domain/media/title.dart
  46. +1
    -1
      lib/domain/rss_category.dart
  47. +5
    -5
      lib/domain/rss_cloud.dart
  48. +1
    -1
      lib/domain/rss_content.dart
  49. +3
    -3
      lib/domain/rss_enclosure.dart
  50. +49
    -43
      lib/domain/rss_feed.dart
  51. +7
    -7
      lib/domain/rss_image.dart
  52. +21
    -28
      lib/domain/rss_item.dart
  53. +0
    -83
      lib/domain/rss_item_itunes.dart
  54. +0
    -69
      lib/domain/rss_itunes.dart
  55. +0
    -24
      lib/domain/rss_itunes_category.dart
  56. +0
    -19
      lib/domain/rss_itunes_episode_type.dart
  57. +0
    -14
      lib/domain/rss_itunes_image.dart
  58. +0
    -18
      lib/domain/rss_itunes_owner.dart
  59. +0
    -17
      lib/domain/rss_itunes_type.dart
  60. +1
    -1
      lib/domain/rss_source.dart
  61. +51
    -0
      lib/domain/syndication/syndication.dart
  62. +24
    -0
      lib/util/datetime.dart
  63. +0
    -28
      lib/util/helpers.dart
  64. +40
    -0
      lib/util/xml.dart
  65. +3
    -4
      pubspec.yaml
  66. +128
    -124
      test/atom_test.dart
  67. +221
    -177
      test/rss_test.dart
  68. +1
    -1
      test/xml/Atom.xml
  69. +5
    -1
      test/xml/RSS-DC.xml
  70. +2
    -5
      test/xml/RSS-Itunes.xml
  71. +35
    -0
      test/xml/RSS-RDF.xml
  72. +24
    -0
      test/xml/RSS-Syndication.xml

+ 19
- 0
.github/workflows/dart.yml Zobrazit soubor

@@ -0,0 +1,19 @@
name: Dart CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
runs-on: ubuntu-latest
container:
image: google/dart:latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: pub get
- name: Run tests
run: pub run test

+ 17
- 0
CHANGELOG.md Zobrazit soubor

@@ -1,10 +1,27 @@
# Changelog
## [0.6.0](https://pub.dartlang.org/packages/webfeed/versions/0.6.0)
- Refactor util/xml.dart
- Support RDF feed
- Support Syndication namespace

## [0.5.2](https://pub.dartlang.org/packages/webfeed/versions/0.5.2)
- Lower the xml package version constraints

## [0.5.1](https://pub.dartlang.org/packages/webfeed/versions/0.5.1)
- Support iTunes namespace [#19](https://github.com/witochandra/webfeed/pull/19)
- Parse date strings into DateTime [#22](https://github.com/witochandra/webfeed/pull/22)
- Add created & modified into dublin core namespace [#27](https://github.com/witochandra/webfeed/pull/27)
- Upgrade xml package [#28](https://github.com/witochandra/webfeed/issues/28)
- Fix linting warnings

## [0.4.2](https://pub.dartlang.org/packages/webfeed/versions/0.4.2)
### Fixed
- Bad import in `rss_content.dart` & `rss_source.dart`

## [0.4.1](https://pub.dartlang.org/packages/webfeed/versions/0.4.1)
### Added
- Support `author` in RssFeed

## [0.4.0](https://pub.dartlang.org/packages/webfeed/versions/0.4.0)
### Added
- Support for dublin core namespace


+ 6
- 4
README.md Zobrazit soubor

@@ -7,17 +7,19 @@ A dart package for parsing RSS and Atom feed.

### Features

- [x] RSS
- [x] RSS (0.9, 1.0, & 2.0)
- [x] Atom
- [x] Namespaces
- [x] Media RSS
- [x] Dublin Core
- [x] iTunes
- [x] Syndication

### Installing

Add this line into your `pubspec.yaml`
```
webfeed: ^0.4.2
webfeed: ^0.6.0
```

Import the package into your dart code using:
@@ -29,8 +31,8 @@ import 'package:webfeed/webfeed.dart';

To parse string into `RssFeed` object use:
```
var rssFeed = new RssFeed.parse(xmlString); // for parsing RSS feed
var atomFeed = new AtomFeed.parse(xmlString); // for parsing Atom feed
var rssFeed = RssFeed.parse(xmlString); // for parsing RSS feed
var atomFeed = AtomFeed.parse(xmlString); // for parsing Atom feed
```

### Preview


+ 2
- 3
analysis_options.yaml Zobrazit soubor

@@ -1,7 +1,4 @@
analyzer:
language:
enablePreviewDart2: true
strong-mode: true
errors:
unused_import: error
unused_local_variable: error
@@ -35,3 +32,5 @@ linter:
- prefer_typing_uninitialized_variables
- slash_for_doc_comments
- type_init_formals
- unnecessary_new
- prefer_single_quotes

+ 11
- 16
example/main.dart Zobrazit soubor

@@ -1,24 +1,19 @@
import 'package:http/http.dart' as http;
import 'package:webfeed/webfeed.dart';

void main() {
var client = new http.Client();
void main() async {
var client = http.Client();

// RSS feed
client.get("https://developer.apple.com/news/releases/rss/releases.rss").then((response) {
return response.body;
}).then((bodyString) {
var channel = new RssFeed.parse(bodyString);
print(channel);
return channel;
});
var response = await client
.get('https://developer.apple.com/news/releases/rss/releases.rss');
var channel = RssFeed.parse(response.body);
print(channel);

// Atom feed
client.get("https://www.theverge.com/rss/index.xml").then((response) {
return response.body;
}).then((bodyString) {
var feed = new AtomFeed.parse(bodyString);
print(feed);
return feed;
});
response = await client.get('https://www.theverge.com/rss/index.xml');
var feed = AtomFeed.parse(response.body);
print(feed);

client.close();
}

+ 3
- 3
lib/domain/atom_category.dart Zobrazit soubor

@@ -8,9 +8,9 @@ class AtomCategory {
AtomCategory(this.term, this.scheme, this.label);

factory AtomCategory.parse(XmlElement element) {
var term = element.getAttribute("term");
var scheme = element.getAttribute("scheme");
var label = element.getAttribute("label");
var term = element.getAttribute('term');
var scheme = element.getAttribute('scheme');
var label = element.getAttribute('label');
return AtomCategory(term, scheme, label);
}
}

+ 35
- 31
lib/domain/atom_feed.dart Zobrazit soubor

@@ -3,13 +3,14 @@ import 'package:webfeed/domain/atom_generator.dart';
import 'package:webfeed/domain/atom_item.dart';
import 'package:webfeed/domain/atom_link.dart';
import 'package:webfeed/domain/atom_person.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/datetime.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class AtomFeed {
final String id;
final String title;
final String updated;
final DateTime updated;
final List<AtomItem> items;

final List<AtomLink> links;
@@ -39,39 +40,42 @@ class AtomFeed {
});

factory AtomFeed.parse(String xmlString) {
var document = parse(xmlString);
XmlElement feedElement;
try {
feedElement = document.findElements("feed").first;
} on StateError {
throw new ArgumentError("feed not found");
var document = XmlDocument.parse(xmlString);
var feedElement = findFirstElement(document, 'feed');
if (feedElement == null) {
throw ArgumentError('feed not found');
}

return AtomFeed(
id: findElementOrNull(feedElement, "id")?.text,
title: findElementOrNull(feedElement, "title")?.text,
updated: findElementOrNull(feedElement, "updated")?.text,
items: feedElement.findElements("entry").map((element) {
return AtomItem.parse(element);
}).toList(),
links: feedElement.findElements("link").map((element) {
return AtomLink.parse(element);
}).toList(),
authors: feedElement.findElements("author").map((element) {
return AtomPerson.parse(element);
}).toList(),
contributors: feedElement.findElements("contributor").map((element) {
return AtomPerson.parse(element);
}).toList(),
categories: feedElement.findElements("category").map((element) {
return AtomCategory.parse(element);
}).toList(),
id: findFirstElement(feedElement, 'id')?.text,
title: findFirstElement(feedElement, 'title')?.text,
updated: parseDateTime(findFirstElement(feedElement, 'updated')?.text),
items: feedElement
.findElements('entry')
.map((e) => AtomItem.parse(e))
.toList(),
links: feedElement
.findElements('link')
.map((e) => AtomLink.parse(e))
.toList(),
authors: feedElement
.findElements('author')
.map((e) => AtomPerson.parse(e))
.toList(),
contributors: feedElement
.findElements('contributor')
.map((e) => AtomPerson.parse(e))
.toList(),
categories: feedElement
.findElements('category')
.map((e) => AtomCategory.parse(e))
.toList(),
generator:
AtomGenerator.parse(findElementOrNull(feedElement, "generator")),
icon: findElementOrNull(feedElement, "icon")?.text,
logo: findElementOrNull(feedElement, "logo")?.text,
rights: findElementOrNull(feedElement, "rights")?.text,
subtitle: findElementOrNull(feedElement, "subtitle")?.text,
AtomGenerator.parse(findFirstElement(feedElement, 'generator')),
icon: findFirstElement(feedElement, 'icon')?.text,
logo: findFirstElement(feedElement, 'logo')?.text,
rights: findFirstElement(feedElement, 'rights')?.text,
subtitle: findFirstElement(feedElement, 'subtitle')?.text,
);
}
}

+ 3
- 3
lib/domain/atom_generator.dart Zobrazit soubor

@@ -11,9 +11,9 @@ class AtomGenerator {
if (element == null) {
return null;
}
var uri = element.getAttribute("uri");
var version = element.getAttribute("version");
var uri = element.getAttribute('uri');
var version = element.getAttribute('version');
var value = element.text;
return new AtomGenerator(uri, version, value);
return AtomGenerator(uri, version, value);
}
}

+ 25
- 22
lib/domain/atom_item.dart Zobrazit soubor

@@ -3,13 +3,14 @@ import 'package:webfeed/domain/atom_link.dart';
import 'package:webfeed/domain/atom_person.dart';
import 'package:webfeed/domain/atom_source.dart';
import 'package:webfeed/domain/media/media.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/datetime.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class AtomItem {
final String id;
final String title;
final String updated;
final DateTime updated;

final List<AtomPerson> authors;
final List<AtomLink> links;
@@ -40,26 +41,28 @@ class AtomItem {

factory AtomItem.parse(XmlElement element) {
return AtomItem(
id: findElementOrNull(element, "id")?.text,
title: findElementOrNull(element, "title")?.text,
updated: findElementOrNull(element, "updated")?.text,
authors: element.findElements("author").map((element) {
return AtomPerson.parse(element);
}).toList(),
links: element.findElements("link").map((element) {
return AtomLink.parse(element);
}).toList(),
categories: element.findElements("category").map((element) {
return AtomCategory.parse(element);
}).toList(),
contributors: element.findElements("contributor").map((element) {
return AtomPerson.parse(element);
}).toList(),
source: AtomSource.parse(findElementOrNull(element, "source")),
published: findElementOrNull(element, "published")?.text,
content: findElementOrNull(element, "content")?.text,
summary: findElementOrNull(element, "summary")?.text,
rights: findElementOrNull(element, "rights")?.text,
id: findFirstElement(element, 'id')?.text,
title: findFirstElement(element, 'title')?.text,
updated: parseDateTime(findFirstElement(element, 'updated')?.text),
authors: element
.findElements('author')
.map((e) => AtomPerson.parse(e))
.toList(),
links:
element.findElements('link').map((e) => AtomLink.parse(e)).toList(),
categories: element
.findElements('category')
.map((e) => AtomCategory.parse(e))
.toList(),
contributors: element
.findElements('contributor')
.map((e) => AtomPerson.parse(e))
.toList(),
source: AtomSource.parse(findFirstElement(element, 'source')),
published: findFirstElement(element, 'published')?.text,
content: findFirstElement(element, 'content')?.text,
summary: findFirstElement(element, 'summary')?.text,
rights: findFirstElement(element, 'rights')?.text,
media: Media.parse(element),
);
}


+ 7
- 7
lib/domain/atom_link.dart Zobrazit soubor

@@ -18,14 +18,14 @@ class AtomLink {
);

factory AtomLink.parse(XmlElement element) {
var href = element.getAttribute("href");
var rel = element.getAttribute("rel");
var type = element.getAttribute("type");
var title = element.getAttribute("title");
var hreflang = element.getAttribute("hreflang");
var href = element.getAttribute('href');
var rel = element.getAttribute('rel');
var type = element.getAttribute('type');
var title = element.getAttribute('title');
var hreflang = element.getAttribute('hreflang');
var length = 0;
if (element.getAttribute("length") != null) {
length = int.parse(element.getAttribute("length"));
if (element.getAttribute('length') != null) {
length = int.parse(element.getAttribute('length'));
}
return AtomLink(href, rel, type, hreflang, title, length);
}


+ 7
- 6
lib/domain/atom_person.dart Zobrazit soubor

@@ -1,4 +1,4 @@
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class AtomPerson {
@@ -6,12 +6,13 @@ class AtomPerson {
final String uri;
final String email;

AtomPerson(this.name, this.uri, this.email);
AtomPerson({this.name, this.uri, this.email});

factory AtomPerson.parse(XmlElement element) {
var name = findElementOrNull(element, "name")?.text;
var uri = findElementOrNull(element, "uri")?.text;
var email = findElementOrNull(element, "email")?.text;
return AtomPerson(name, uri, email);
return AtomPerson(
name: findFirstElement(element, 'name')?.text,
uri: findFirstElement(element, 'uri')?.text,
email: findFirstElement(element, 'email')?.text,
);
}
}

+ 11
- 7
lib/domain/atom_source.dart Zobrazit soubor

@@ -1,4 +1,4 @@
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class AtomSource {
@@ -6,16 +6,20 @@ class AtomSource {
final String title;
final String updated;

AtomSource(this.id, this.title, this.updated);
AtomSource({
this.id,
this.title,
this.updated,
});

factory AtomSource.parse(XmlElement element) {
if (element == null) {
return null;
}
var id = findElementOrNull(element, "id")?.text;
var title = findElementOrNull(element, "title")?.text;
var updated = findElementOrNull(element, "updated")?.text;
return AtomSource(id, title, updated);
return AtomSource(
id: findFirstElement(element, 'id')?.text,
title: findFirstElement(element, 'title')?.text,
updated: findFirstElement(element, 'updated')?.text,
);
}
}

+ 24
- 17
lib/domain/dublin_core/dublin_core.dart Zobrazit soubor

@@ -1,4 +1,5 @@
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/datetime.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class DublinCore {
@@ -8,7 +9,9 @@ class DublinCore {
final String subject;
final String publisher;
final String contributor;
final String date;
final DateTime date;
final DateTime created;
final DateTime modified;
final String type;
final String format;
final String identifier;
@@ -26,6 +29,8 @@ class DublinCore {
this.publisher,
this.contributor,
this.date,
this.created,
this.modified,
this.type,
this.format,
this.identifier,
@@ -41,21 +46,23 @@ class DublinCore {
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,
title: findFirstElement(element, 'dc:title')?.text,
description: findFirstElement(element, 'dc:description')?.text,
creator: findFirstElement(element, 'dc:creator')?.text,
subject: findFirstElement(element, 'dc:subject')?.text,
publisher: findFirstElement(element, 'dc:publisher')?.text,
contributor: findFirstElement(element, 'dc:contributor')?.text,
date: parseDateTime(findFirstElement(element, 'dc:date')?.text),
created: parseDateTime(findFirstElement(element, 'dc:created')?.text),
modified: parseDateTime(findFirstElement(element, 'dc:modified')?.text),
type: findFirstElement(element, 'dc:type')?.text,
format: findFirstElement(element, 'dc:format')?.text,
identifier: findFirstElement(element, 'dc:identifier')?.text,
source: findFirstElement(element, 'dc:source')?.text,
language: findFirstElement(element, 'dc:language')?.text,
relation: findFirstElement(element, 'dc:relation')?.text,
coverage: findFirstElement(element, 'dc:coverage')?.text,
rights: findFirstElement(element, 'dc:rights')?.text,
);
}
}

+ 102
- 0
lib/domain/itunes/itunes.dart Zobrazit soubor

@@ -0,0 +1,102 @@
import 'package:webfeed/domain/itunes/itunes_category.dart';
import 'package:webfeed/domain/itunes/itunes_episode_type.dart';
import 'package:webfeed/domain/itunes/itunes_image.dart';
import 'package:webfeed/domain/itunes/itunes_owner.dart';
import 'package:webfeed/domain/itunes/itunes_type.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class Itunes {
final String author;
final String summary;
final bool explicit;
final String title;
final String subtitle;
final ItunesOwner owner;
final List<String> keywords;
final ItunesImage image;
final List<ItunesCategory> categories;
final ItunesType type;
final String newFeedUrl;
final bool block;
final bool complete;
final int episode;
final int season;
final Duration duration;
final ItunesEpisodeType episodeType;

Itunes({
this.author,
this.summary,
this.explicit,
this.title,
this.subtitle,
this.owner,
this.keywords,
this.image,
this.categories,
this.type,
this.newFeedUrl,
this.block,
this.complete,
this.episode,
this.season,
this.duration,
this.episodeType,
});

factory Itunes.parse(XmlElement element) {
if (element == null) {
return null;
}
var episodeStr = findFirstElement(element, 'itunes:episode')?.text;
var seasonStr = findFirstElement(element, 'itunes:season')?.text;
var durationStr = findFirstElement(element, 'itunes:duration')?.text;
return Itunes(
author: findFirstElement(element, 'itunes:author')?.text,
summary: findFirstElement(element, 'itunes:summary')?.text,
explicit: parseBoolLiteral(element, 'itunes:explicit'),
title: findFirstElement(element, 'itunes:title')?.text,
subtitle: findFirstElement(element, 'itunes:subtitle')?.text,
owner: ItunesOwner.parse(findFirstElement(element, 'itunes:owner')),
keywords: findFirstElement(element, 'itunes:keywords')
?.text
?.split(',')
?.map((keyword) => keyword.trim())
?.toList() ??
[],
image: ItunesImage.parse(findFirstElement(element, 'itunes:image')),
categories: findElements(element, 'itunes:category')
.map((e) => ItunesCategory.parse(e))
.toList(),
type: newItunesType(findFirstElement(element, 'itunes:type')),
newFeedUrl: findFirstElement(element, 'itunes:new-feed-url')?.text,
block: parseBoolLiteral(element, 'itunes:block'),
complete: parseBoolLiteral(element, 'itunes:complete'),
episode: episodeStr == null ? null : int.parse(episodeStr),
season: seasonStr == null ? null : int.parse(seasonStr),
duration: durationStr == null ? null : _parseDuration(durationStr),
episodeType:
newItunesEpisodeType(findFirstElement(element, 'itunes:episodeType')),
);
}

static Duration _parseDuration(String s) {
var hours = 0;
var minutes = 0;
var seconds = 0;
var parts = s.split(':');
if (parts.length > 2) {
hours = int.parse(parts[parts.length - 3]);
}
if (parts.length > 1) {
minutes = int.parse(parts[parts.length - 2]);
}
seconds = int.parse(parts[parts.length - 1]);
return Duration(
hours: hours,
minutes: minutes,
seconds: seconds,
);
}
}

+ 20
- 0
lib/domain/itunes/itunes_category.dart Zobrazit soubor

@@ -0,0 +1,20 @@
import 'package:xml/xml.dart';

class ItunesCategory {
final String category;
final List<String> subCategories;

ItunesCategory({this.category, this.subCategories});

factory ItunesCategory.parse(XmlElement element) {
if (element == null) return null;
return ItunesCategory(
category: element.getAttribute('text')?.trim(),
subCategories: element
.findElements('itunes:category')
?.map((e) => e.getAttribute('text')?.trim())
?.toList() ??
[],
);
}
}

+ 16
- 0
lib/domain/itunes/itunes_episode_type.dart Zobrazit soubor

@@ -0,0 +1,16 @@
import 'package:xml/xml.dart';

enum ItunesEpisodeType { full, trailer, bonus, unknown }

ItunesEpisodeType newItunesEpisodeType(XmlElement element) {
switch (element?.text) {
case 'full':
return ItunesEpisodeType.full;
case 'trailer':
return ItunesEpisodeType.trailer;
case 'bonus':
return ItunesEpisodeType.bonus;
default:
return ItunesEpisodeType.unknown;
}
}

+ 14
- 0
lib/domain/itunes/itunes_image.dart Zobrazit soubor

@@ -0,0 +1,14 @@
import 'package:xml/xml.dart';

class ItunesImage {
final String href;

ItunesImage({this.href});

factory ItunesImage.parse(XmlElement element) {
if (element == null) return null;
return ItunesImage(
href: element.getAttribute('href')?.trim(),
);
}
}

+ 17
- 0
lib/domain/itunes/itunes_owner.dart Zobrazit soubor

@@ -0,0 +1,17 @@
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class ItunesOwner {
final String name;
final String email;

ItunesOwner({this.name, this.email});

factory ItunesOwner.parse(XmlElement element) {
if (element == null) return null;
return ItunesOwner(
name: findFirstElement(element, 'itunes:name')?.text?.trim(),
email: findFirstElement(element, 'itunes:email')?.text?.trim(),
);
}
}

+ 14
- 0
lib/domain/itunes/itunes_type.dart Zobrazit soubor

@@ -0,0 +1,14 @@
import 'package:xml/xml.dart';

enum ItunesType { episodic, serial, unknown }

ItunesType newItunesType(XmlElement element) {
switch (element?.text) {
case 'episodic':
return ItunesType.episodic;
case 'serial':
return ItunesType.serial;
default:
return ItunesType.unknown;
}
}

+ 3
- 3
lib/domain/media/category.dart Zobrazit soubor

@@ -15,9 +15,9 @@ class Category {
if (element == null) {
return null;
}
return new Category(
scheme: element.getAttribute("scheme"),
label: element.getAttribute("label"),
return Category(
scheme: element.getAttribute('scheme'),
label: element.getAttribute('label'),
value: element.text,
);
}


+ 8
- 8
lib/domain/media/community.dart Zobrazit soubor

@@ -1,7 +1,7 @@
import 'package:webfeed/domain/media/star_rating.dart';
import 'package:webfeed/domain/media/statistics.dart';
import 'package:webfeed/domain/media/tags.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class Community {
@@ -19,15 +19,15 @@ class Community {
if (element == null) {
return null;
}
return new Community(
starRating: new StarRating.parse(
findElementOrNull(element, "media:starRating"),
return Community(
starRating: StarRating.parse(
findFirstElement(element, 'media:starRating'),
),
statistics: new Statistics.parse(
findElementOrNull(element, "media:statistics"),
statistics: Statistics.parse(
findFirstElement(element, 'media:statistics'),
),
tags: new Tags.parse(
findElementOrNull(element, "media:tags"),
tags: Tags.parse(
findFirstElement(element, 'media:tags'),
),
);
}


+ 15
- 15
lib/domain/media/content.dart Zobrazit soubor

@@ -34,23 +34,23 @@ class Content {
});

factory Content.parse(XmlElement element) {
return new Content(
url: element.getAttribute("url"),
type: element.getAttribute("type"),
fileSize: int.tryParse(element.getAttribute("fileSize") ?? "0"),
medium: element.getAttribute("medium"),
isDefault: element.getAttribute("isDefault") == "true",
expression: element.getAttribute("expression"),
bitrate: int.tryParse(element.getAttribute("bitrate") ?? "0"),
framerate: double.tryParse(element.getAttribute("framerate") ?? "0"),
return Content(
url: element.getAttribute('url'),
type: element.getAttribute('type'),
fileSize: int.tryParse(element.getAttribute('fileSize') ?? '0'),
medium: element.getAttribute('medium'),
isDefault: element.getAttribute('isDefault') == 'true',
expression: element.getAttribute('expression'),
bitrate: int.tryParse(element.getAttribute('bitrate') ?? '0'),
framerate: double.tryParse(element.getAttribute('framerate') ?? '0'),
samplingrate: double.tryParse(
element.getAttribute("samplingrate") ?? "0",
element.getAttribute('samplingrate') ?? '0',
),
channels: int.tryParse(element.getAttribute("channels") ?? "0"),
duration: int.tryParse(element.getAttribute("duration") ?? "0"),
height: int.tryParse(element.getAttribute("height") ?? "0"),
width: int.tryParse(element.getAttribute("width") ?? "0"),
lang: element.getAttribute("lang"),
channels: int.tryParse(element.getAttribute('channels') ?? '0'),
duration: int.tryParse(element.getAttribute('duration') ?? '0'),
height: int.tryParse(element.getAttribute('height') ?? '0'),
width: int.tryParse(element.getAttribute('width') ?? '0'),
lang: element.getAttribute('lang'),
);
}
}

+ 2
- 2
lib/domain/media/copyright.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Copyright {
if (element == null) {
return null;
}
return new Copyright(
url: element.getAttribute("url"),
return Copyright(
url: element.getAttribute('url'),
value: element.text,
);
}


+ 3
- 3
lib/domain/media/credit.dart Zobrazit soubor

@@ -12,9 +12,9 @@ class Credit {
});

factory Credit.parse(XmlElement element) {
return new Credit(
role: element.getAttribute("role"),
scheme: element.getAttribute("scheme"),
return Credit(
role: element.getAttribute('role'),
scheme: element.getAttribute('scheme'),
value: element.text,
);
}


+ 2
- 2
lib/domain/media/description.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Description {
if (element == null) {
return null;
}
return new Description(
type: element.getAttribute("type"),
return Description(
type: element.getAttribute('type'),
value: element.text,
);
}


+ 6
- 6
lib/domain/media/embed.dart Zobrazit soubor

@@ -18,12 +18,12 @@ class Embed {
if (element == null) {
return null;
}
return new Embed(
url: element.getAttribute("url"),
width: int.tryParse(element.getAttribute("width") ?? "0"),
height: int.tryParse(element.getAttribute("height") ?? "0"),
params: element.findElements("media:param").map((e) {
return new Param.parse(e);
return Embed(
url: element.getAttribute('url'),
width: int.tryParse(element.getAttribute('width') ?? '0'),
height: int.tryParse(element.getAttribute('height') ?? '0'),
params: element.findElements('media:param').map((e) {
return Param.parse(e);
}).toList(),
);
}


+ 10
- 10
lib/domain/media/group.dart Zobrazit soubor

@@ -2,7 +2,7 @@ import 'package:webfeed/domain/media/category.dart';
import 'package:webfeed/domain/media/content.dart';
import 'package:webfeed/domain/media/credit.dart';
import 'package:webfeed/domain/media/rating.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class Group {
@@ -22,18 +22,18 @@ class Group {
if (element == null) {
return null;
}
return new Group(
contents: element.findElements("media:content").map((e) {
return new Content.parse(e);
return Group(
contents: element.findElements('media:content').map((e) {
return Content.parse(e);
}).toList(),
credits: element.findElements("media:credit").map((e) {
return new Credit.parse(e);
credits: element.findElements('media:credit').map((e) {
return Credit.parse(e);
}).toList(),
category: new Category.parse(
findElementOrNull(element, "media:category"),
category: Category.parse(
findFirstElement(element, 'media:category'),
),
rating: new Rating.parse(
findElementOrNull(element, "media:rating"),
rating: Rating.parse(
findFirstElement(element, 'media:rating'),
),
);
}


+ 2
- 2
lib/domain/media/hash.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Hash {
if (element == null) {
return null;
}
return new Hash(
algo: element.getAttribute("algo"),
return Hash(
algo: element.getAttribute('algo'),
value: element.text,
);
}


+ 3
- 3
lib/domain/media/license.dart Zobrazit soubor

@@ -15,9 +15,9 @@ class License {
if (element == null) {
return null;
}
return new License(
type: element.getAttribute("type"),
href: element.getAttribute("href"),
return License(
type: element.getAttribute('type'),
href: element.getAttribute('href'),
value: element.text,
);
}


+ 52
- 52
lib/domain/media/media.dart Zobrazit soubor

@@ -19,7 +19,7 @@ import 'package:webfeed/domain/media/status.dart';
import 'package:webfeed/domain/media/text.dart';
import 'package:webfeed/domain/media/thumbnail.dart';
import 'package:webfeed/domain/media/title.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class Media {
@@ -78,90 +78,90 @@ class Media {
});

factory Media.parse(XmlElement element) {
return new Media(
group: new Group.parse(
findElementOrNull(element, "media:group"),
return Media(
group: Group.parse(
findFirstElement(element, 'media:group'),
),
contents: element.findElements("media:content").map((e) {
return new Content.parse(e);
contents: element.findElements('media:content').map((e) {
return Content.parse(e);
}).toList(),
credits: element.findElements("media:credit").map((e) {
return new Credit.parse(e);
credits: element.findElements('media:credit').map((e) {
return Credit.parse(e);
}).toList(),
category: new Category.parse(
findElementOrNull(element, "media:category"),
category: Category.parse(
findFirstElement(element, 'media:category'),
),
rating: new Rating.parse(
findElementOrNull(element, "media:rating"),
rating: Rating.parse(
findFirstElement(element, 'media:rating'),
),
title: new Title.parse(
findElementOrNull(element, "media:title"),
title: Title.parse(
findFirstElement(element, 'media:title'),
),
description: new Description.parse(
findElementOrNull(element, "media:description"),
description: Description.parse(
findFirstElement(element, 'media:description'),
),
keywords: findElementOrNull(element, "media:keywords")?.text,
thumbnails: element.findElements("media:thumbnail").map((e) {
return new Thumbnail.parse(e);
keywords: findFirstElement(element, 'media:keywords')?.text,
thumbnails: element.findElements('media:thumbnail').map((e) {
return Thumbnail.parse(e);
}).toList(),
hash: new Hash.parse(
findElementOrNull(element, "media:hash"),
hash: Hash.parse(
findFirstElement(element, 'media:hash'),
),
player: new Player.parse(
findElementOrNull(element, "media:player"),
player: Player.parse(
findFirstElement(element, 'media:player'),
),
copyright: new Copyright.parse(
findElementOrNull(element, "media:copyright"),
copyright: Copyright.parse(
findFirstElement(element, 'media:copyright'),
),
text: new Text.parse(
findElementOrNull(element, "media:text"),
text: Text.parse(
findFirstElement(element, 'media:text'),
),
restriction: new Restriction.parse(
findElementOrNull(element, "media:restriction"),
restriction: Restriction.parse(
findFirstElement(element, 'media:restriction'),
),
community: new Community.parse(
findElementOrNull(element, "media:community"),
community: Community.parse(
findFirstElement(element, 'media:community'),
),
comments: findElementOrNull(element, "media:comments")
?.findElements("media:comment")
comments: findFirstElement(element, 'media:comments')
?.findElements('media:comment')
?.map((e) {
return e.text;
})?.toList() ??
[],
embed: new Embed.parse(
findElementOrNull(element, "media:embed"),
embed: Embed.parse(
findFirstElement(element, 'media:embed'),
),
responses: findElementOrNull(element, "media:responses")
?.findElements("media:response")
responses: findFirstElement(element, 'media:responses')
?.findElements('media:response')
?.map((e) {
return e.text;
})?.toList() ??
[],
backLinks: findElementOrNull(element, "media:backLinks")
?.findElements("media:backLink")
backLinks: findFirstElement(element, 'media:backLinks')
?.findElements('media:backLink')
?.map((e) {
return e.text;
})?.toList() ??
[],
status: new Status.parse(
findElementOrNull(element, "media:status"),
status: Status.parse(
findFirstElement(element, 'media:status'),
),
prices: element.findElements("media:price").map((e) {
return new Price.parse(e);
prices: element.findElements('media:price').map((e) {
return Price.parse(e);
}).toList(),
license: new License.parse(
findElementOrNull(element, "media:license"),
license: License.parse(
findFirstElement(element, 'media:license'),
),
peerLink: new PeerLink.parse(
findElementOrNull(element, "media:peerLink"),
peerLink: PeerLink.parse(
findFirstElement(element, 'media:peerLink'),
),
rights: new Rights.parse(
findElementOrNull(element, "media:rights"),
rights: Rights.parse(
findFirstElement(element, 'media:rights'),
),
scenes: findElementOrNull(element, "media:scenes")
?.findElements("media:scene")
scenes: findFirstElement(element, 'media:scenes')
?.findElements('media:scene')
?.map((e) {
return new Scene.parse(e);
return Scene.parse(e);
})?.toList() ??
[],
);


+ 2
- 2
lib/domain/media/param.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Param {
if (element == null) {
return null;
}
return new Param(
name: element.getAttribute("name"),
return Param(
name: element.getAttribute('name'),
value: element.text,
);
}


+ 3
- 3
lib/domain/media/peer_link.dart Zobrazit soubor

@@ -15,9 +15,9 @@ class PeerLink {
if (element == null) {
return null;
}
return new PeerLink(
type: element.getAttribute("type"),
href: element.getAttribute("href"),
return PeerLink(
type: element.getAttribute('type'),
href: element.getAttribute('href'),
value: element.text,
);
}


+ 4
- 4
lib/domain/media/player.dart Zobrazit soubor

@@ -17,10 +17,10 @@ class Player {
if (element == null) {
return null;
}
return new Player(
url: element.getAttribute("url"),
width: int.tryParse(element.getAttribute("width") ?? "0"),
height: int.tryParse(element.getAttribute("height") ?? "0"),
return Player(
url: element.getAttribute('url'),
width: int.tryParse(element.getAttribute('width') ?? '0'),
height: int.tryParse(element.getAttribute('height') ?? '0'),
value: element.text,
);
}


+ 5
- 5
lib/domain/media/price.dart Zobrazit soubor

@@ -14,11 +14,11 @@ class Price {
});

factory Price.parse(XmlElement element) {
return new Price(
price: double.tryParse(element.getAttribute("price") ?? "0"),
type: element.getAttribute("type"),
info: element.getAttribute("info"),
currency: element.getAttribute("currency"),
return Price(
price: double.tryParse(element.getAttribute('price') ?? '0'),
type: element.getAttribute('type'),
info: element.getAttribute('info'),
currency: element.getAttribute('currency'),
);
}
}

+ 2
- 2
lib/domain/media/rating.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Rating {
if (element == null) {
return null;
}
return new Rating(
scheme: element.getAttribute("scheme"),
return Rating(
scheme: element.getAttribute('scheme'),
value: element.text,
);
}


+ 3
- 3
lib/domain/media/restriction.dart Zobrazit soubor

@@ -15,9 +15,9 @@ class Restriction {
if (element == null) {
return null;
}
return new Restriction(
relationship: element.getAttribute("relationship"),
type: element.getAttribute("type"),
return Restriction(
relationship: element.getAttribute('relationship'),
type: element.getAttribute('type'),
value: element.text,
);
}


+ 2
- 2
lib/domain/media/rights.dart Zobrazit soubor

@@ -11,8 +11,8 @@ class Rights {
if (element == null) {
return null;
}
return new Rights(
status: element.getAttribute("status"),
return Rights(
status: element.getAttribute('status'),
);
}
}

+ 6
- 6
lib/domain/media/scene.dart Zobrazit soubor

@@ -1,4 +1,4 @@
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class Scene {
@@ -18,11 +18,11 @@ class Scene {
if (element == null) {
return null;
}
return new Scene(
title: findElementOrNull(element, "sceneTitle")?.text,
description: findElementOrNull(element, "sceneDescription")?.text,
startTime: findElementOrNull(element, "sceneStartTime")?.text,
endTime: findElementOrNull(element, "sceneEndTime")?.text,
return Scene(
title: findFirstElement(element, 'sceneTitle')?.text,
description: findFirstElement(element, 'sceneDescription')?.text,
startTime: findFirstElement(element, 'sceneStartTime')?.text,
endTime: findFirstElement(element, 'sceneEndTime')?.text,
);
}
}

+ 5
- 5
lib/domain/media/star_rating.dart Zobrazit soubor

@@ -14,11 +14,11 @@ class StarRating {
});

factory StarRating.parse(XmlElement element) {
return new StarRating(
average: double.tryParse(element.getAttribute("average") ?? "0"),
count: int.tryParse(element.getAttribute("count") ?? "0"),
min: int.tryParse(element.getAttribute("min") ?? "0"),
max: int.tryParse(element.getAttribute("max") ?? "0"),
return StarRating(
average: double.tryParse(element.getAttribute('average') ?? '0'),
count: int.tryParse(element.getAttribute('count') ?? '0'),
min: int.tryParse(element.getAttribute('min') ?? '0'),
max: int.tryParse(element.getAttribute('max') ?? '0'),
);
}
}

+ 3
- 3
lib/domain/media/statistics.dart Zobrazit soubor

@@ -10,9 +10,9 @@ class Statistics {
});

factory Statistics.parse(XmlElement element) {
return new Statistics(
views: int.tryParse(element.getAttribute("views") ?? "0"),
favorites: int.tryParse(element.getAttribute("favorites") ?? "0"),
return Statistics(
views: int.tryParse(element.getAttribute('views') ?? '0'),
favorites: int.tryParse(element.getAttribute('favorites') ?? '0'),
);
}
}

+ 3
- 3
lib/domain/media/status.dart Zobrazit soubor

@@ -13,9 +13,9 @@ class Status {
if (element == null) {
return null;
}
return new Status(
state: element.getAttribute("state"),
reason: element.getAttribute("reason"),
return Status(
state: element.getAttribute('state'),
reason: element.getAttribute('reason'),
);
}
}

+ 2
- 2
lib/domain/media/tags.dart Zobrazit soubor

@@ -13,9 +13,9 @@ class Tags {
if (element == null) {
return null;
}
return new Tags(
return Tags(
tags: element.text,
weight: int.tryParse(element.getAttribute("weight") ?? "1"),
weight: int.tryParse(element.getAttribute('weight') ?? '1'),
);
}
}

+ 5
- 5
lib/domain/media/text.dart Zobrazit soubor

@@ -19,11 +19,11 @@ class Text {
if (element == null) {
return null;
}
return new Text(
type: element.getAttribute("type"),
lang: element.getAttribute("lang"),
start: element.getAttribute("start"),
end: element.getAttribute("end"),
return Text(
type: element.getAttribute('type'),
lang: element.getAttribute('lang'),
start: element.getAttribute('start'),
end: element.getAttribute('end'),
value: element.text,
);
}


+ 5
- 5
lib/domain/media/thumbnail.dart Zobrazit soubor

@@ -14,11 +14,11 @@ class Thumbnail {
});

factory Thumbnail.parse(XmlElement element) {
return new Thumbnail(
url: element.getAttribute("url"),
width: element.getAttribute("width"),
height: element.getAttribute("height"),
time: element.getAttribute("time"),
return Thumbnail(
url: element.getAttribute('url'),
width: element.getAttribute('width'),
height: element.getAttribute('height'),
time: element.getAttribute('time'),
);
}
}

+ 2
- 2
lib/domain/media/title.dart Zobrazit soubor

@@ -13,8 +13,8 @@ class Title {
if (element == null) {
return null;
}
return new Title(
type: element.getAttribute("type"),
return Title(
type: element.getAttribute('type'),
value: element.text,
);
}


+ 1
- 1
lib/domain/rss_category.dart Zobrazit soubor

@@ -10,7 +10,7 @@ class RssCategory {
if (element == null) {
return null;
}
var domain = element.getAttribute("domain");
var domain = element.getAttribute('domain');
var value = element.text;

return RssCategory(domain, value);


+ 5
- 5
lib/domain/rss_cloud.dart Zobrazit soubor

@@ -19,11 +19,11 @@ class RssCloud {
if (node == null) {
return null;
}
var domain = node.getAttribute("domain");
var port = node.getAttribute("port");
var path = node.getAttribute("path");
var registerProcedure = node.getAttribute("registerProcedure");
var protocol = node.getAttribute("protocol");
var domain = node.getAttribute('domain');
var port = node.getAttribute('port');
var path = node.getAttribute('path');
var registerProcedure = node.getAttribute('registerProcedure');
var protocol = node.getAttribute('protocol');
return RssCloud(domain, port, path, registerProcedure, protocol);
}
}

+ 1
- 1
lib/domain/rss_content.dart Zobrazit soubor

@@ -1,6 +1,6 @@
import 'package:xml/xml.dart';

final _imagesRegExp = new RegExp(
final _imagesRegExp = RegExp(
"<img\\s.*?src=(?:'|\")([^'\">]+)(?:'|\")",
multiLine: true,
caseSensitive: false,


+ 3
- 3
lib/domain/rss_enclosure.dart Zobrazit soubor

@@ -11,9 +11,9 @@ class RssEnclosure {
if (element == null) {
return null;
}
var url = element.getAttribute("url");
var type = element.getAttribute("type");
var length = int.tryParse(element.getAttribute("length") ?? "0");
var url = element.getAttribute('url');
var type = element.getAttribute('type');
var length = int.tryParse(element.getAttribute('length') ?? '0');
return RssEnclosure(url, type, length);
}
}

+ 49
- 43
lib/domain/rss_feed.dart Zobrazit soubor

@@ -1,15 +1,15 @@
import 'dart:core';

import 'package:webfeed/domain/dublin_core/dublin_core.dart';
import 'package:webfeed/domain/itunes/itunes.dart';
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/util/helpers.dart';
import 'package:webfeed/domain/syndication/syndication.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

import 'rss_itunes.dart';

class RssFeed {
final String title;
final String author;
@@ -32,7 +32,8 @@ class RssFeed {
final String webMaster;
final int ttl;
final DublinCore dc;
final RssItunes itunes;
final Itunes itunes;
final Syndication syndication;

RssFeed({
this.title,
@@ -56,53 +57,58 @@ class RssFeed {
this.ttl,
this.dc,
this.itunes,
this.syndication,
});

factory RssFeed.parse(String xmlString) {
var document = parse(xmlString);
XmlElement channelElement;
try {
channelElement = document.findAllElements("channel").first;
} on StateError {
throw ArgumentError("channel not found");
var document = XmlDocument.parse(xmlString);
var rss = findFirstElement(document, 'rss');
var rdf = findFirstElement(document, 'rdf:RDF');
if (rss == null && rdf == null) {
throw ArgumentError('not a rss feed');
}
var channelElement = findFirstElement(rss ?? rdf, 'channel');
if (channelElement == null) {
throw ArgumentError('channel not found');
}

return RssFeed(
title: findElementOrNull(channelElement, "title")?.text,
author: findElementOrNull(channelElement, "author")?.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() ??
title: findFirstElement(channelElement, 'title')?.text,
author: findFirstElement(channelElement, 'author')?.text,
description: findFirstElement(channelElement, 'description')?.text,
link: findFirstElement(channelElement, 'link')?.text,
items: (rss != null ? channelElement : rdf)
.findElements('item')
.map((e) => RssItem.parse(e))
.toList(),
image: RssImage.parse(
findFirstElement(rss != null ? channelElement : rdf, 'image')),
cloud: RssCloud.parse(findFirstElement(channelElement, 'cloud')),
categories: channelElement
.findElements('category')
.map((e) => RssCategory.parse(e))
.toList(),
skipDays: findFirstElement(channelElement, 'skipDays')
?.findAllElements('day')
?.map((e) => e.text)
?.toList() ??
[],
skipHours: findElementOrNull(channelElement, "skipHours")
?.findAllElements("hour")
?.map((element) {
return int.tryParse(element.text ?? "0");
})?.toList() ??
skipHours: findFirstElement(channelElement, 'skipHours')
?.findAllElements('hour')
?.map((e) => int.tryParse(e.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"),
lastBuildDate: findFirstElement(channelElement, 'lastBuildDate')?.text,
language: findFirstElement(channelElement, 'language')?.text,
generator: findFirstElement(channelElement, 'generator')?.text,
copyright: findFirstElement(channelElement, 'copyright')?.text,
docs: findFirstElement(channelElement, 'docs')?.text,
managingEditor: findFirstElement(channelElement, 'managingEditor')?.text,
rating: findFirstElement(channelElement, 'rating')?.text,
webMaster: findFirstElement(channelElement, 'webMaster')?.text,
ttl: int.tryParse(findFirstElement(channelElement, 'ttl')?.text ?? '0'),
dc: DublinCore.parse(channelElement),
itunes: RssItunes.parse(channelElement),
itunes: Itunes.parse(channelElement),
syndication: Syndication.parse(channelElement),
);
}
}

+ 7
- 7
lib/domain/rss_image.dart Zobrazit soubor

@@ -1,4 +1,4 @@
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

class RssImage {
@@ -6,16 +6,16 @@ class RssImage {
final String url;
final String link;

RssImage(this.title, this.url, this.link);
RssImage({this.title, this.url, this.link});

factory RssImage.parse(XmlElement element) {
if (element == null) {
return null;
}
var title = findElementOrNull(element, "title")?.text;
var url = findElementOrNull(element, "url")?.text;
var link = findElementOrNull(element, "link")?.text;
return RssImage(title, url, link);
return RssImage(
title: findFirstElement(element, 'title')?.text,
url: findFirstElement(element, 'url')?.text,
link: findFirstElement(element, 'link')?.text,
);
}
}

+ 21
- 28
lib/domain/rss_item.dart Zobrazit soubor

@@ -1,15 +1,14 @@
import 'package:intl/intl.dart';
import 'package:webfeed/domain/dublin_core/dublin_core.dart';
import 'package:webfeed/domain/itunes/itunes.dart';
import 'package:webfeed/domain/media/media.dart';
import 'package:webfeed/domain/rss_category.dart';
import 'package:webfeed/domain/rss_content.dart';
import 'package:webfeed/domain/rss_enclosure.dart';
import 'package:webfeed/domain/rss_source.dart';
import 'package:webfeed/util/helpers.dart';
import 'package:webfeed/util/datetime.dart';
import 'package:webfeed/util/xml.dart';
import 'package:xml/xml.dart';

import 'rss_item_itunes.dart';

class RssItem {
final String title;
final String description;
@@ -25,7 +24,7 @@ class RssItem {
final Media media;
final RssEnclosure enclosure;
final DublinCore dc;
final RssItemItunes itunes;
final Itunes itunes;

RssItem({
this.title,
@@ -33,7 +32,7 @@ class RssItem {
this.link,
this.categories,
this.guid,
String pubDate,
this.pubDate,
this.author,
this.comments,
this.source,
@@ -42,33 +41,27 @@ class RssItem {
this.enclosure,
this.dc,
this.itunes,
})
: this.pubDate = _parsePubDate(pubDate);
});

factory RssItem.parse(XmlElement element) {
return RssItem(
title: findElementOrNull(element, "title")?.text,
description: findElementOrNull(element, "description")?.text,
link: findElementOrNull(element, "link")?.text,
categories: element.findElements("category").map((element) {
return RssCategory.parse(element);
}).toList(),
guid: findElementOrNull(element, "guid")?.text,
pubDate: findElementOrNull(element, "pubDate")?.text,
author: findElementOrNull(element, "author")?.text,
comments: findElementOrNull(element, "comments")?.text,
source: RssSource.parse(findElementOrNull(element, "source")),
content: RssContent.parse(findElementOrNull(element, "content:encoded")),
title: findFirstElement(element, 'title')?.text,
description: findFirstElement(element, 'description')?.text,
link: findFirstElement(element, 'link')?.text,
categories: element
.findElements('category')
.map((e) => RssCategory.parse(e))
.toList(),
guid: findFirstElement(element, 'guid')?.text,
pubDate: parseDateTime(findFirstElement(element, 'pubDate')?.text),
author: findFirstElement(element, 'author')?.text,
comments: findFirstElement(element, 'comments')?.text,
source: RssSource.parse(findFirstElement(element, 'source')),
content: RssContent.parse(findFirstElement(element, 'content:encoded')),
media: Media.parse(element),
enclosure: RssEnclosure.parse(findElementOrNull(element, "enclosure")),
enclosure: RssEnclosure.parse(findFirstElement(element, 'enclosure')),
dc: DublinCore.parse(element),
itunes: RssItemItunes.parse(element),
itunes: Itunes.parse(element),
);
}

static _parsePubDate(pubDate) {
if (pubDate == null) return null;
//Locale for pubDate is always en_US, regardless of device locale
return DateFormat('EEE, dd MMM yyyy HH:mm:ss Z', 'en_US').parse(pubDate);
}
}

+ 0
- 83
lib/domain/rss_item_itunes.dart Zobrazit soubor

@@ -1,83 +0,0 @@
import 'package:webfeed/util/helpers.dart';
import 'package:xml/xml.dart';

import 'rss_itunes_category.dart';
import 'rss_itunes_episode_type.dart';
import 'rss_itunes_image.dart';

class RssItemItunes {
final String title;
final int episode;
final int season;
final Duration duration;
final RssItunesEpisodeType episodeType;
final String author;
final String summary;
final bool explicit;
final String subtitle;
final List<String> keywords;
final RssItunesImage image;
final RssItunesCategory category;
final bool block;

RssItemItunes({
this.title,
this.episode,
this.season,
this.duration,
this.episodeType,
this.author,
this.summary,
this.explicit,
this.subtitle,
this.keywords,
this.image,
this.category,
this.block,
});

factory RssItemItunes.parse(XmlElement element) {
if (element == null) {
return null;
}
var episodeStr = findElementOrNull(element, "itunes:episode")?.text?.trim();
var seasonStr = findElementOrNull(element, "itunes:season")?.text?.trim();
var durationStr = findElementOrNull(element, "itunes:duration")?.text?.trim();

return RssItemItunes(
title: findElementOrNull(element, "itunes:title")?.text?.trim(),
episode: episodeStr == null ? null : int.parse(episodeStr),
season: seasonStr == null ? null : int.parse(seasonStr),
duration: durationStr == null ? null : parseDuration(durationStr),
episodeType: newRssItunesEpisodeType(findElementOrNull(element, "itunes:episodeType")),
author: findElementOrNull(element, "itunes:author")?.text?.trim(),
summary: findElementOrNull(element, "itunes:summary")?.text?.trim(),
explicit: parseBoolLiteral(element, "itunes:explicit"),
subtitle: findElementOrNull(element, "itunes:subtitle")?.text?.trim(),
keywords: findElementOrNull(element, "itunes:keywords")?.text?.split(",")?.map((keyword) => keyword.trim())?.toList(),
image: RssItunesImage.parse(findElementOrNull(element, "itunes:image")),
category: RssItunesCategory.parse(
findElementOrNull(element, "itunes:category")),
block: parseBoolLiteral(element, "itunes:block"),
);
}
}

Duration parseDuration(String s) {
var hours = 0;
var minutes = 0;
var seconds = 0;
var parts = s.split(':');
if (parts.length > 2) {
hours = int.parse(parts[parts.length - 3]);
}
if (parts.length > 1) {
minutes = int.parse(parts[parts.length - 2]);
}
seconds = int.parse(parts[parts.length - 1]);
return Duration(
hours: hours,
minutes: minutes,
seconds: seconds,
);
}

+ 0
- 69
lib/domain/rss_itunes.dart Zobrazit soubor

@@ -1,69 +0,0 @@
import 'package:xml/xml.dart';

import 'package:webfeed/util/helpers.dart';

import 'rss_itunes_category.dart';
import 'rss_itunes_image.dart';
import 'rss_itunes_owner.dart';
import 'rss_itunes_type.dart';

class RssItunes {
final String author;
final String summary;
final bool explicit;
final String title;
final String subtitle;
final RssItunesOwner owner;
final List<String> keywords;
final RssItunesImage image;
final List<RssItunesCategory> categories;
final RssItunesType type;
final String newFeedUrl;
final bool block;
final bool complete;

RssItunes({
this.author,
this.summary,
this.explicit,
this.title,
this.subtitle,
this.owner,
this.keywords,
this.image,
this.categories,
this.type,
this.newFeedUrl,
this.block,
this.complete,
});

factory RssItunes.parse(XmlElement element) {
if (element == null) {
return null;
}
return RssItunes(
author: findElementOrNull(element, "itunes:author")?.text?.trim(),
summary: findElementOrNull(element, "itunes:summary")?.text?.trim(),
explicit: parseBoolLiteral(element, "itunes:explicit"),
title: findElementOrNull(element, "itunes:title")?.text?.trim(),
subtitle: findElementOrNull(element, "itunes:subtitle")?.text?.trim(),
owner: RssItunesOwner.parse(findElementOrNull(element, "itunes:owner")),
keywords: findElementOrNull(element, "itunes:keywords")
?.text
?.split(",")
?.map((keyword) => keyword.trim())
?.toList(),
image: RssItunesImage.parse(findElementOrNull(element, "itunes:image")),
categories: findAllDirectElementsOrNull(element, "itunes:category")
.map((ele) => RssItunesCategory.parse(ele))
.toList(),
type: newRssItunesType(findElementOrNull(element, "itunes:type")),
newFeedUrl:
findElementOrNull(element, "itunes:new-feed-url")?.text?.trim(),
block: parseBoolLiteral(element, "itunes:block"),
complete: parseBoolLiteral(element, "itunes:complete"),
);
}
}


+ 0
- 24
lib/domain/rss_itunes_category.dart Zobrazit soubor

@@ -1,24 +0,0 @@
import 'package:xml/xml.dart';

class RssItunesCategory {
final String category;
final List<String> subCategories;

RssItunesCategory({this.category, this.subCategories});

factory RssItunesCategory.parse(XmlElement element) {
if (element == null) return null;

Iterable<XmlElement> subCategories;
try {
subCategories = element.findElements("itunes:category");
} on StateError {
subCategories = null;
}
return RssItunesCategory(
category: element.getAttribute("text")?.trim(),
subCategories:
subCategories?.map((ele) => ele.getAttribute("text")?.trim())?.toList(),
);
}
}

+ 0
- 19
lib/domain/rss_itunes_episode_type.dart Zobrazit soubor

@@ -1,19 +0,0 @@
import 'package:xml/xml.dart';

enum RssItunesEpisodeType {full, trailer, bonus}

RssItunesEpisodeType newRssItunesEpisodeType(XmlElement element) {
// "full" is default type
if (element == null) return RssItunesEpisodeType.full;

switch (element.text) {
case "full":
return RssItunesEpisodeType.full;
case "trailer":
return RssItunesEpisodeType.trailer;
case "bonus":
return RssItunesEpisodeType.bonus;
default:
return null;
}
}

+ 0
- 14
lib/domain/rss_itunes_image.dart Zobrazit soubor

@@ -1,14 +0,0 @@
import 'package:xml/xml.dart';

class RssItunesImage {
final String href;

RssItunesImage({this.href});

factory RssItunesImage.parse(XmlElement element) {
if (element == null) return null;
return RssItunesImage(
href: element.getAttribute("href")?.trim(),
);
}
}

+ 0
- 18
lib/domain/rss_itunes_owner.dart Zobrazit soubor

@@ -1,18 +0,0 @@
import 'package:xml/xml.dart';

import '../util/helpers.dart';

class RssItunesOwner {
final String name;
final String email;

RssItunesOwner({this.name, this.email});

factory RssItunesOwner.parse(XmlElement element) {
if (element == null) return null;
return RssItunesOwner(
name: findElementOrNull(element, "itunes:name")?.text?.trim(),
email: findElementOrNull(element, "itunes:email")?.text?.trim(),
);
}
}

+ 0
- 17
lib/domain/rss_itunes_type.dart Zobrazit soubor

@@ -1,17 +0,0 @@
import 'package:xml/xml.dart';

enum RssItunesType { episodic, serial }

RssItunesType newRssItunesType(XmlElement element) {
// "episodic" is default type
if (element == null) return RssItunesType.episodic;

switch (element.text) {
case "episodic":
return RssItunesType.episodic;
case "serial":
return RssItunesType.serial;
default:
return null;
}
}

+ 1
- 1
lib/domain/rss_source.dart Zobrazit soubor

@@ -10,7 +10,7 @@ class RssSource {
if (element == null) {
return null;
}
var url = element.getAttribute("url");
var url = element.getAttribute('url');
var value = element.text;

return RssSource(url, value);


+ 51
- 0
lib/domain/syndication/syndication.dart Zobrazit soubor

@@ -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),
);
}
}

+ 24
- 0
lib/util/datetime.dart Zobrazit soubor

@@ -0,0 +1,24 @@
import 'package:intl/intl.dart';

var rfc822DateFormat = DateFormat('EEE, dd MMM yyyy HH:mm:ss Z', 'en_US');

DateTime parseDateTime(dateString) {
if (dateString == null) return null;
return _parseRfc822DateTime(dateString) ?? _parseIso8601DateTime(dateString);
}

DateTime _parseRfc822DateTime(dateString) {
try {
return rfc822DateFormat.parse(dateString);
} on FormatException {
return null;
}
}

DateTime _parseIso8601DateTime(dateString) {
try {
return DateTime.parse(dateString);
} on FormatException {
return null;
}
}

+ 0
- 28
lib/util/helpers.dart Zobrazit soubor

@@ -1,28 +0,0 @@
import 'dart:core';

import 'package:xml/xml.dart';

XmlElement findElementOrNull(XmlElement element, String name,
{String namespace}) {
try {
return element.findAllElements(name, namespace: namespace).first;
} on StateError {
return null;
}
}

List<XmlElement> findAllDirectElementsOrNull(XmlElement element, String name,
{String namespace}) {
try {
return element.findElements(name, namespace: namespace).toList();
} on StateError {
return null;
}
}

bool parseBoolLiteral(XmlElement element, String tagName) {
var v = findElementOrNull(element, tagName)?.text?.toLowerCase()?.trim();
if (v == null) return null;
return ["yes", "true"].contains(v);
}


+ 40
- 0
lib/util/xml.dart Zobrazit soubor

@@ -0,0 +1,40 @@
import 'dart:core';

import 'package:xml/xml.dart';

XmlElement findFirstElement(
XmlNode node,
String name, {
bool recursive = false,
String namespace,
}) {
try {
return findElements(node, name, recursive: recursive, namespace: namespace)
?.first;
} on StateError {
return null;
}
}

Iterable<XmlElement> findElements(
XmlNode node,
String name, {
bool recursive = false,
String namespace,
}) {
try {
if (recursive) {
return node.findAllElements(name, namespace: namespace);
} else {
return node.findElements(name, namespace: namespace);
}
} on StateError {
return null;
}
}

bool parseBoolLiteral(XmlElement element, String tagName) {
var v = findFirstElement(element, tagName)?.text?.toLowerCase()?.trim();
if (v == null) return false;
return ['yes', 'true'].contains(v);
}

+ 3
- 4
pubspec.yaml Zobrazit soubor

@@ -1,12 +1,11 @@
name: webfeed
version: 0.4.2
description: webfeed is a dart package for parsing RSS and Atom feeds. Media & DublinCore namespaces are also supported.
author: Wito Chandra <wito.c.91@gmail.com>
version: 0.6.0
description: webfeed is a dart package for parsing RSS and Atom feeds. Media, DublinCore, iTunes, Syndication namespaces are also supported.
homepage: https://github.com/witochandra/webfeed
environment:
sdk: ">=2.0.0 <3.0.0"
dependencies:
xml: "^3.0.0"
xml: "^4.2.0"
intl: "^0.16.0"
dev_dependencies:
test: ^1.3.0


+ 128
- 124
test/atom_test.dart Zobrazit soubor

@@ -5,113 +5,113 @@ import 'package:test/test.dart';
import 'package:webfeed/webfeed.dart';

void main() {
test("parse Invalid.xml", () {
var xmlString = new File("test/xml/Invalid.xml").readAsStringSync();
test('parse Invalid.xml', () {
var xmlString = File('test/xml/Invalid.xml').readAsStringSync();

try {
new AtomFeed.parse(xmlString);
fail("Should throw Argument Error");
AtomFeed.parse(xmlString);
fail('Should throw Argument Error');
} on ArgumentError {}
});

test("parse Atom.xml", () {
var xmlString = new File("test/xml/Atom.xml").readAsStringSync();
test('parse Atom.xml', () {
var xmlString = File('test/xml/Atom.xml').readAsStringSync();

var feed = new AtomFeed.parse(xmlString);
var feed = AtomFeed.parse(xmlString);

expect(feed.id, "foo-bar-id");
expect(feed.title, "Foo bar news");
expect(feed.updated, "2018-04-06T13:02:46Z");
expect(feed.id, 'foo-bar-id');
expect(feed.title, 'Foo bar news');
expect(feed.updated, DateTime.utc(2018, 4, 6, 13, 2, 46));

expect(feed.links.length, 2);
expect(feed.links.first.rel, "foo");
expect(feed.links.first.type, "text/html");
expect(feed.links.first.hreflang, "en");
expect(feed.links.first.href, "http://foo.bar.news/");
expect(feed.links.first.title, "Foo bar news html");
expect(feed.links.first.rel, 'foo');
expect(feed.links.first.type, 'text/html');
expect(feed.links.first.hreflang, 'en');
expect(feed.links.first.href, 'http://foo.bar.news/');
expect(feed.links.first.title, 'Foo bar news html');
expect(feed.links.first.length, 1000);

expect(feed.authors.length, 2);
expect(feed.authors.first.name, "Alice");
expect(feed.authors.first.uri, "http://foo.bar.news/people/alice");
expect(feed.authors.first.email, "alice@foo.bar.news");
expect(feed.authors.first.name, 'Alice');
expect(feed.authors.first.uri, 'http://foo.bar.news/people/alice');
expect(feed.authors.first.email, 'alice@foo.bar.news');

expect(feed.contributors.length, 2);
expect(feed.contributors.first.name, "Charlie");
expect(feed.contributors.first.uri, "http://foo.bar.news/people/charlie");
expect(feed.contributors.first.email, "charlie@foo.bar.news");
expect(feed.contributors.first.name, 'Charlie');
expect(feed.contributors.first.uri, 'http://foo.bar.news/people/charlie');
expect(feed.contributors.first.email, 'charlie@foo.bar.news');

expect(feed.categories.length, 2);
expect(feed.categories.first.term, "foo category");
expect(feed.categories.first.scheme, "this-is-foo-scheme");
expect(feed.categories.first.label, "this is foo label");
expect(feed.categories.first.term, 'foo category');
expect(feed.categories.first.scheme, 'this-is-foo-scheme');
expect(feed.categories.first.label, 'this is foo label');

expect(feed.generator.uri, "http://foo.bar.news/generator");
expect(feed.generator.version, "1.0");
expect(feed.generator.value, "Foo bar generator");
expect(feed.generator.uri, 'http://foo.bar.news/generator');
expect(feed.generator.version, '1.0');
expect(feed.generator.value, 'Foo bar generator');

expect(feed.icon, "http://foo.bar.news/icon.png");
expect(feed.logo, "http://foo.bar.news/logo.png");
expect(feed.subtitle, "This is subtitle");
expect(feed.icon, 'http://foo.bar.news/icon.png');
expect(feed.logo, 'http://foo.bar.news/logo.png');
expect(feed.subtitle, 'This is subtitle');

expect(feed.items.length, 2);
var item = feed.items.first;
expect(item.id, "foo-bar-entry-id-1");
expect(item.title, "Foo bar item 1");
expect(item.updated, "2018-04-06T13:02:47Z");
expect(item.id, 'foo-bar-entry-id-1');
expect(item.title, 'Foo bar item 1');
expect(item.updated, DateTime.utc(2018, 4, 6, 13, 2, 40));

expect(item.authors.length, 2);
expect(item.authors.first.name, "Ellie");
expect(item.authors.first.uri, "http://foo.bar.news/people/ellie");
expect(item.authors.first.email, "ellie@foo.bar.news");
expect(item.authors.first.name, 'Ellie');
expect(item.authors.first.uri, 'http://foo.bar.news/people/ellie');
expect(item.authors.first.email, 'ellie@foo.bar.news');

expect(item.links.length, 2);
expect(item.links.first.rel, "foo entry");
expect(item.links.first.type, "text/html");
expect(item.links.first.hreflang, "en");
expect(item.links.first.href, "http://foo.bar.news/entry");
expect(item.links.first.title, "Foo bar news html");
expect(item.links.first.rel, 'foo entry');
expect(item.links.first.type, 'text/html');
expect(item.links.first.hreflang, 'en');
expect(item.links.first.href, 'http://foo.bar.news/entry');
expect(item.links.first.title, 'Foo bar news html');
expect(item.links.first.length, 1000);

expect(item.categories.length, 2);
expect(item.categories.first.term, "foo entry category");
expect(item.categories.first.scheme, "this-is-foo-entry-scheme");
expect(item.categories.first.label, "this is foo entry label");
expect(item.categories.first.term, 'foo entry category');
expect(item.categories.first.scheme, 'this-is-foo-entry-scheme');
expect(item.categories.first.label, 'this is foo entry label');

expect(item.contributors.length, 2);
expect(item.contributors.first.name, "Gin");
expect(item.contributors.first.uri, "http://foo.bar.news/people/gin");
expect(item.contributors.first.email, "gin@foo.bar.news");
expect(item.published, "2018-04-06T13:02:49Z");
expect(item.summary, "This is summary 1");
expect(item.content, "This is content 1");
expect(item.rights, "This is rights 1");
expect(item.contributors.first.name, 'Gin');
expect(item.contributors.first.uri, 'http://foo.bar.news/people/gin');
expect(item.contributors.first.email, 'gin@foo.bar.news');
expect(item.published, '2018-04-06T13:02:49Z');
expect(item.summary, 'This is summary 1');
expect(item.content, 'This is content 1');
expect(item.rights, 'This is rights 1');
});
test("parse Atom-Media.xml", (){
var xmlString = new File("test/xml/Atom-Media.xml").readAsStringSync();
test('parse Atom-Media.xml', () {
var xmlString = File('test/xml/Atom-Media.xml').readAsStringSync();

var feed = new AtomFeed.parse(xmlString);
expect(feed.id, "foo-bar-id");
expect(feed.title, "Foo bar news");
expect(feed.updated, "2018-04-06T13:02:46Z");
var feed = AtomFeed.parse(xmlString);
expect(feed.id, 'foo-bar-id');
expect(feed.title, 'Foo bar news');
expect(feed.updated, DateTime.utc(2018, 4, 6, 13, 2, 46));

expect(feed.items.length, 1);
var item = feed.items.first;
expect(item.media.group.contents.length, 5);
expect(item.media.group.credits.length, 2);
expect(item.media.group.category.value, "music/artist name/album/song");
expect(item.media.group.rating.value, "nonadult");
expect(item.media.group.category.value, 'music/artist name/album/song');
expect(item.media.group.rating.value, 'nonadult');

expect(item.media.contents.length, 2);
var mediaContent = item.media.contents.first;
expect(mediaContent.url, "http://www.foo.com/video.mov");
expect(mediaContent.type, "video/quicktime");
expect(mediaContent.url, 'http://www.foo.com/video.mov');
expect(mediaContent.type, 'video/quicktime');
expect(mediaContent.fileSize, 2000);
expect(mediaContent.medium, "video");
expect(mediaContent.medium, 'video');
expect(mediaContent.isDefault, true);
expect(mediaContent.expression, "full");
expect(mediaContent.expression, 'full');
expect(mediaContent.bitrate, 128);
expect(mediaContent.framerate, 25);
expect(mediaContent.samplingrate, 44.1);
@@ -119,52 +119,54 @@ void main() {

expect(item.media.credits.length, 2);
var mediaCredit = item.media.credits.first;
expect(mediaCredit.role, "owner1");
expect(mediaCredit.scheme, "urn:yvs");
expect(mediaCredit.value, "copyright holder of the entity");
expect(mediaCredit.role, 'owner1');
expect(mediaCredit.scheme, 'urn:yvs');
expect(mediaCredit.value, 'copyright holder of the entity');

expect(item.media.category.scheme, "http://search.yahoo.com/mrss/category_ schema");
expect(item.media.category.label, "Music");
expect(item.media.category.value, "music/artist/album/song");
expect(item.media.category.scheme,
'http://search.yahoo.com/mrss/category_ schema');
expect(item.media.category.label, 'Music');
expect(item.media.category.value, 'music/artist/album/song');

expect(item.media.rating.scheme, "urn:simple");
expect(item.media.rating.value, "adult");
expect(item.media.rating.scheme, 'urn:simple');
expect(item.media.rating.value, 'adult');

expect(item.media.title.type, "plain");
expect(item.media.title.type, 'plain');
expect(item.media.title.value, "The Judy's -- The Moo Song");

expect(item.media.description.type, "plain");
expect(item.media.description.value, "This was some really bizarre band I listened to as a young lad.");
expect(item.media.keywords, "kitty, cat, big dog, yarn, fluffy");
expect(item.media.description.type, 'plain');
expect(item.media.description.value,
'This was some really bizarre band I listened to as a young lad.');

expect(item.media.keywords, 'kitty, cat, big dog, yarn, fluffy');

expect(item.media.thumbnails.length, 2);
var mediaThumbnail = item.media.thumbnails.first;
expect(mediaThumbnail.url, "http://www.foo.com/keyframe1.jpg");
expect(mediaThumbnail.width, "75");
expect(mediaThumbnail.height, "50");
expect(mediaThumbnail.time, "12:05:01.123");
expect(mediaThumbnail.url, 'http://www.foo.com/keyframe1.jpg');
expect(mediaThumbnail.width, '75');
expect(mediaThumbnail.height, '50');
expect(mediaThumbnail.time, '12:05:01.123');

expect(item.media.hash.algo, "md5");
expect(item.media.hash.value, "dfdec888b72151965a34b4b59031290a");
expect(item.media.hash.algo, 'md5');
expect(item.media.hash.value, 'dfdec888b72151965a34b4b59031290a');

expect(item.media.player.url, "http://www.foo.com/player?id=1111");
expect(item.media.player.url, 'http://www.foo.com/player?id=1111');
expect(item.media.player.width, 400);
expect(item.media.player.height, 200);
expect(item.media.player.value, "");
expect(item.media.player.value, '');

expect(item.media.copyright.url, "http://blah.com/additional-info.html");
expect(item.media.copyright.value, "2005 FooBar Media");
expect(item.media.copyright.url, 'http://blah.com/additional-info.html');
expect(item.media.copyright.value, '2005 FooBar Media');

expect(item.media.text.type, "plain");
expect(item.media.text.lang, "en");
expect(item.media.text.start, "00:00:03.000");
expect(item.media.text.end, "00:00:10.000");
expect(item.media.text.value, " Oh, say, can you see");
expect(item.media.text.type, 'plain');
expect(item.media.text.lang, 'en');
expect(item.media.text.start, '00:00:03.000');
expect(item.media.text.end, '00:00:10.000');
expect(item.media.text.value, ' Oh, say, can you see');

expect(item.media.restriction.relationship, "allow");
expect(item.media.restriction.type, "country");
expect(item.media.restriction.value, "au us");
expect(item.media.restriction.relationship, 'allow');
expect(item.media.restriction.type, 'country');
expect(item.media.restriction.value, 'au us');

expect(item.media.community.starRating.average, 3.5);
expect(item.media.community.starRating.count, 20);
@@ -172,56 +174,58 @@ void main() {
expect(item.media.community.starRating.max, 10);
expect(item.media.community.statistics.views, 5);
expect(item.media.community.statistics.favorites, 4);
expect(item.media.community.tags.tags, "news: 5, abc:3");
expect(item.media.community.tags.tags, 'news: 5, abc:3');
expect(item.media.community.tags.weight, 1);

expect(item.media.comments.length, 2);
expect(item.media.comments.first, "comment1");
expect(item.media.comments.last, "comment2");
expect(item.media.comments.first, 'comment1');
expect(item.media.comments.last, 'comment2');

expect(item.media.embed.url, "http://www.foo.com/player.swf");
expect(item.media.embed.url, 'http://www.foo.com/player.swf');
expect(item.media.embed.width, 512);
expect(item.media.embed.height, 323);
expect(item.media.embed.params.length, 5);
expect(item.media.embed.params.first.name, "type");
expect(item.media.embed.params.first.value, "application/x-shockwave-flash");
expect(item.media.embed.params.first.name, 'type');
expect(
item.media.embed.params.first.value, 'application/x-shockwave-flash');

expect(item.media.responses.length, 2);
expect(item.media.responses.first, "http://www.response1.com");
expect(item.media.responses.last, "http://www.response2.com");
expect(item.media.responses.first, 'http://www.response1.com');
expect(item.media.responses.last, 'http://www.response2.com');

expect(item.media.backLinks.length, 2);
expect(item.media.backLinks.first, "http://www.backlink1.com");
expect(item.media.backLinks.last, "http://www.backlink2.com");
expect(item.media.backLinks.first, 'http://www.backlink1.com');
expect(item.media.backLinks.last, 'http://www.backlink2.com');

expect(item.media.status.state, "active");
expect(item.media.status.state, 'active');
expect(item.media.status.reason, null);

expect(item.media.prices.length, 2);
expect(item.media.prices.first.price, 19.99);
expect(item.media.prices.first.type, "rent");
expect(item.media.prices.first.info, "http://www.dummy.jp/package_info.html");
expect(item.media.prices.first.currency, "EUR");
expect(item.media.prices.first.type, 'rent');
expect(
item.media.prices.first.info, 'http://www.dummy.jp/package_info.html');
expect(item.media.prices.first.currency, 'EUR');

expect(item.media.license.type, "text/html");
expect(item.media.license.href, "http://www.licensehost.com/license");
expect(item.media.license.value, " Sample license for a video");
expect(item.media.license.type, 'text/html');
expect(item.media.license.href, 'http://www.licensehost.com/license');
expect(item.media.license.value, ' Sample license for a video');

expect(item.media.peerLink.type, "application/x-bittorrent");
expect(item.media.peerLink.href, "http://www.foo.org/sampleFile.torrent");
expect(item.media.peerLink.value, "");
expect(item.media.peerLink.type, 'application/x-bittorrent');
expect(item.media.peerLink.href, 'http://www.foo.org/sampleFile.torrent');
expect(item.media.peerLink.value, '');

expect(item.media.rights.status, "official");
expect(item.media.rights.status, 'official');

expect(item.media.scenes.length, 2);
expect(item.media.scenes.first.title, "sceneTitle1");
expect(item.media.scenes.first.description, "sceneDesc1");
expect(item.media.scenes.first.startTime, "00:15");
expect(item.media.scenes.first.endTime, "00:45");
expect(item.media.scenes.first.title, 'sceneTitle1');
expect(item.media.scenes.first.description, 'sceneDesc1');
expect(item.media.scenes.first.startTime, '00:15');
expect(item.media.scenes.first.endTime, '00:45');
});

test("parse Atom-Empty.xml", () {
var xmlString = File("test/xml/Atom-Empty.xml").readAsStringSync();
test('parse Atom-Empty.xml', () {
var xmlString = File('test/xml/Atom-Empty.xml').readAsStringSync();

var feed = AtomFeed.parse(xmlString);



+ 221
- 177
test/rss_test.dart Zobrazit soubor

@@ -2,60 +2,60 @@ import 'dart:core';
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';

import 'package:webfeed/domain/rss_itunes_type.dart';
import 'package:webfeed/domain/rss_itunes_episode_type.dart';

void main() {
test("parse Invalid.xml", () {
var xmlString = new File("test/xml/Invalid.xml").readAsStringSync();
test('parse Invalid.xml', () {
var xmlString = File('test/xml/Invalid.xml').readAsStringSync();

try {
new RssFeed.parse(xmlString);
fail("Should throw Argument Error");
RssFeed.parse(xmlString);
fail('Should throw Argument Error');
} on ArgumentError {}
});
test("parse RSS.xml", () {
var xmlString = new File("test/xml/RSS.xml").readAsStringSync();
test('parse RSS.xml', () {
var xmlString = File('test/xml/RSS.xml').readAsStringSync();

var feed = new RssFeed.parse(xmlString);
var feed = RssFeed.parse(xmlString);

expect(feed.title, "News - Foo bar News");
expect(feed.title, 'News - Foo bar News');
expect(feed.description,
"Foo bar News and Updates feed provided by Foo bar, Inc.");
expect(feed.link, "https://foo.bar.news/");
expect(feed.author, "hello@world.net");
expect(feed.language, "en-US");
expect(feed.lastBuildDate, "Mon, 26 Mar 2018 14:00:00 PDT");
expect(feed.generator, "Custom");
expect(feed.copyright, "Copyright 2018, Foo bar Inc.");
expect(feed.docs, "https://foo.bar.news/docs");
expect(feed.managingEditor, "alice@foo.bar.news");
expect(feed.rating, "The PICS rating of the feed");
expect(feed.webMaster, "webmaster@foo.bar.news");
'Foo bar News and Updates feed provided by Foo bar, Inc.');
expect(feed.link, 'https://foo.bar.news/');
expect(feed.author, 'hello@world.net');
expect(feed.language, 'en-US');
expect(feed.lastBuildDate, 'Mon, 26 Mar 2018 14:00:00 PDT');
expect(feed.generator, 'Custom');
expect(feed.copyright, 'Copyright 2018, Foo bar Inc.');
expect(feed.docs, 'https://foo.bar.news/docs');
expect(feed.managingEditor, 'alice@foo.bar.news');
expect(feed.rating, 'The PICS rating of the feed');
expect(feed.webMaster, 'webmaster@foo.bar.news');
expect(feed.ttl, 60);

expect(feed.image.title, "Foo bar News");
expect(feed.image.url, "https://foo.bar.news/logo.gif");
expect(feed.image.link, "https://foo.bar.news/");
expect(feed.image.title, 'Foo bar News');
expect(feed.image.url, 'https://foo.bar.news/logo.gif');
expect(feed.image.link, 'https://foo.bar.news/');

expect(feed.cloud.domain, "radio.foo.bar.news");
expect(feed.cloud.port, "80");
expect(feed.cloud.path, "/RPC2");
expect(feed.cloud.registerProcedure, "foo.bar.rssPleaseNotify");
expect(feed.cloud.protocol, "xml-rpc");
expect(feed.cloud.domain, 'radio.foo.bar.news');
expect(feed.cloud.port, '80');
expect(feed.cloud.path, '/RPC2');
expect(feed.cloud.registerProcedure, 'foo.bar.rssPleaseNotify');
expect(feed.cloud.protocol, 'xml-rpc');

expect(feed.categories.length, 2);
expect(feed.categories[0].domain, null);
expect(feed.categories[0].value, "Ipsum");
expect(feed.categories[1].domain, "news");
expect(feed.categories[1].value, "Lorem Ipsum");
expect(feed.categories[0].value, 'Ipsum');
expect(feed.categories[1].domain, 'news');
expect(feed.categories[1].value, 'Lorem Ipsum');

expect(feed.skipDays.length, 3);
expect(feed.skipDays.contains("Monday"), true);
expect(feed.skipDays.contains("Tuesday"), true);
expect(feed.skipDays.contains("Sunday"), true);
expect(feed.skipDays.contains('Monday'), true);
expect(feed.skipDays.contains('Tuesday'), true);
expect(feed.skipDays.contains('Sunday'), true);

expect(feed.skipHours.length, 5);
expect(feed.skipHours.contains(0), true);
@@ -67,56 +67,58 @@ void main() {
expect(feed.items.length, 2);

expect(feed.items.first.title,
"The standard Lorem Ipsum passage, used since the 1500s");
'The standard Lorem Ipsum passage, used since the 1500s');
expect(feed.items.first.description,
"Lorem ipsum dolor sit amet, consectetur adipiscing elit");
expect(feed.items.first.link, "https://foo.bar.news/1");
expect(feed.items.first.guid, "https://foo.bar.news/1?guid");
expect(feed.items.first.pubDate, DateTime(2018, 03, 26, 14)); //Mon, 26 Mar 2018 14:00:00 PDT
expect(feed.items.first.categories.first.domain, "news");
expect(feed.items.first.categories.first.value, "Lorem");
expect(feed.items.first.author, "alice@foo.bar.news");
expect(feed.items.first.source.url, "https://foo.bar.news/1?source");
expect(feed.items.first.source.value, "Foo Bar");
expect(feed.items.first.comments, "https://foo.bar.news/1/comments");
'Lorem ipsum dolor sit amet, consectetur adipiscing elit');
expect(feed.items.first.link, 'https://foo.bar.news/1');
expect(feed.items.first.guid, 'https://foo.bar.news/1?guid');
expect(feed.items.first.pubDate,
DateTime(2018, 03, 26, 14)); //Mon, 26 Mar 2018 14:00:00 PDT
expect(feed.items.first.categories.first.domain, 'news');
expect(feed.items.first.categories.first.value, 'Lorem');
expect(feed.items.first.author, 'alice@foo.bar.news');
expect(feed.items.first.source.url, 'https://foo.bar.news/1?source');
expect(feed.items.first.source.value, 'Foo Bar');
expect(feed.items.first.comments, 'https://foo.bar.news/1/comments');
expect(feed.items.first.enclosure.url,
"http://www.scripting.com/mp3s/weatherReportSuite.mp3");
'http://www.scripting.com/mp3s/weatherReportSuite.mp3');
expect(feed.items.first.enclosure.length, 12216320);
expect(feed.items.first.enclosure.type, "audio/mpeg");
expect(feed.items.first.enclosure.type, 'audio/mpeg');

expect(feed.items.first.content.value,
"<img width=\"1000\" height=\"690\" src=\"https://test.com/image_link\"/> Test content<br />");
'<img width="1000" height="690" src="https://test.com/image_link"/> Test content<br />');
expect(
feed.items.first.content.images.first, "https://test.com/image_link");
feed.items.first.content.images.first, 'https://test.com/image_link');
});
test("parse RSS-Media.xml", () {
var xmlString = new File("test/xml/RSS-Media.xml").readAsStringSync();
test('parse RSS-Media.xml', () {
var xmlString = File('test/xml/RSS-Media.xml').readAsStringSync();

var feed = new RssFeed.parse(xmlString);
expect(feed.title, "Song Site");
var feed = RssFeed.parse(xmlString);
expect(feed.title, 'Song Site');
expect(
feed.description, "Media RSS example with new fields added in v1.5.0");
feed.description, 'Media RSS example with new fields added in v1.5.0');

expect(feed.items.length, 1);

var item = feed.items.first;
expect(item.title, null);
expect(item.link, "http://www.foo.com");
expect(item.pubDate, DateTime(2001, 08, 27, 16, 08, 56)); //Mon, 27 Aug 2001 16:08:56 PST
expect(item.link, 'http://www.foo.com');
expect(item.pubDate,
DateTime(2001, 08, 27, 16, 08, 56)); //Mon, 27 Aug 2001 16:08:56 PST

expect(item.media.group.contents.length, 5);
expect(item.media.group.credits.length, 2);
expect(item.media.group.category.value, "music/artist name/album/song");
expect(item.media.group.rating.value, "nonadult");
expect(item.media.group.category.value, 'music/artist name/album/song');
expect(item.media.group.rating.value, 'nonadult');

expect(item.media.contents.length, 2);
var mediaContent = item.media.contents.first;
expect(mediaContent.url, "http://www.foo.com/video.mov");
expect(mediaContent.type, "video/quicktime");
expect(mediaContent.url, 'http://www.foo.com/video.mov');
expect(mediaContent.type, 'video/quicktime');
expect(mediaContent.fileSize, 2000);
expect(mediaContent.medium, "video");
expect(mediaContent.medium, 'video');
expect(mediaContent.isDefault, true);
expect(mediaContent.expression, "full");
expect(mediaContent.expression, 'full');
expect(mediaContent.bitrate, 128);
expect(mediaContent.framerate, 25);
expect(mediaContent.samplingrate, 44.1);
@@ -124,54 +126,54 @@ void main() {

expect(item.media.credits.length, 2);
var mediaCredit = item.media.credits.first;
expect(mediaCredit.role, "owner1");
expect(mediaCredit.scheme, "urn:yvs");
expect(mediaCredit.value, "copyright holder of the entity");
expect(mediaCredit.role, 'owner1');
expect(mediaCredit.scheme, 'urn:yvs');
expect(mediaCredit.value, 'copyright holder of the entity');

expect(item.media.category.scheme,
"http://search.yahoo.com/mrss/category_ schema");
expect(item.media.category.label, "Music");
expect(item.media.category.value, "music/artist/album/song");
'http://search.yahoo.com/mrss/category_ schema');
expect(item.media.category.label, 'Music');
expect(item.media.category.value, 'music/artist/album/song');

expect(item.media.rating.scheme, "urn:simple");
expect(item.media.rating.value, "adult");
expect(item.media.rating.scheme, 'urn:simple');
expect(item.media.rating.value, 'adult');

expect(item.media.title.type, "plain");
expect(item.media.title.type, 'plain');
expect(item.media.title.value, "The Judy's -- The Moo Song");

expect(item.media.description.type, "plain");
expect(item.media.description.type, 'plain');
expect(item.media.description.value,
"This was some really bizarre band I listened to as a young lad.");
'This was some really bizarre band I listened to as a young lad.');

expect(item.media.keywords, "kitty, cat, big dog, yarn, fluffy");
expect(item.media.keywords, 'kitty, cat, big dog, yarn, fluffy');

expect(item.media.thumbnails.length, 2);
var mediaThumbnail = item.media.thumbnails.first;
expect(mediaThumbnail.url, "http://www.foo.com/keyframe1.jpg");
expect(mediaThumbnail.width, "75");
expect(mediaThumbnail.height, "50");
expect(mediaThumbnail.time, "12:05:01.123");
expect(mediaThumbnail.url, 'http://www.foo.com/keyframe1.jpg');
expect(mediaThumbnail.width, '75');
expect(mediaThumbnail.height, '50');
expect(mediaThumbnail.time, '12:05:01.123');

expect(item.media.hash.algo, "md5");
expect(item.media.hash.value, "dfdec888b72151965a34b4b59031290a");
expect(item.media.hash.algo, 'md5');
expect(item.media.hash.value, 'dfdec888b72151965a34b4b59031290a');

expect(item.media.player.url, "http://www.foo.com/player?id=1111");
expect(item.media.player.url, 'http://www.foo.com/player?id=1111');
expect(item.media.player.width, 400);
expect(item.media.player.height, 200);
expect(item.media.player.value, "");
expect(item.media.player.value, '');

expect(item.media.copyright.url, "http://blah.com/additional-info.html");
expect(item.media.copyright.value, "2005 FooBar Media");
expect(item.media.copyright.url, 'http://blah.com/additional-info.html');
expect(item.media.copyright.value, '2005 FooBar Media');

expect(item.media.text.type, "plain");
expect(item.media.text.lang, "en");
expect(item.media.text.start, "00:00:03.000");
expect(item.media.text.end, "00:00:10.000");
expect(item.media.text.value, " Oh, say, can you see");
expect(item.media.text.type, 'plain');
expect(item.media.text.lang, 'en');
expect(item.media.text.start, '00:00:03.000');
expect(item.media.text.end, '00:00:10.000');
expect(item.media.text.value, ' Oh, say, can you see');

expect(item.media.restriction.relationship, "allow");
expect(item.media.restriction.type, "country");
expect(item.media.restriction.value, "au us");
expect(item.media.restriction.relationship, 'allow');
expect(item.media.restriction.type, 'country');
expect(item.media.restriction.value, 'au us');

expect(item.media.community.starRating.average, 3.5);
expect(item.media.community.starRating.count, 20);
@@ -179,95 +181,99 @@ void main() {
expect(item.media.community.starRating.max, 10);
expect(item.media.community.statistics.views, 5);
expect(item.media.community.statistics.favorites, 4);
expect(item.media.community.tags.tags, "news: 5, abc:3");
expect(item.media.community.tags.tags, 'news: 5, abc:3');
expect(item.media.community.tags.weight, 1);

expect(item.media.comments.length, 2);
expect(item.media.comments.first, "comment1");
expect(item.media.comments.last, "comment2");
expect(item.media.comments.first, 'comment1');
expect(item.media.comments.last, 'comment2');

expect(item.media.embed.url, "http://www.foo.com/player.swf");
expect(item.media.embed.url, 'http://www.foo.com/player.swf');
expect(item.media.embed.width, 512);
expect(item.media.embed.height, 323);
expect(item.media.embed.params.length, 5);
expect(item.media.embed.params.first.name, "type");
expect(item.media.embed.params.first.name, 'type');
expect(
item.media.embed.params.first.value, "application/x-shockwave-flash");
item.media.embed.params.first.value, 'application/x-shockwave-flash');

expect(item.media.responses.length, 2);
expect(item.media.responses.first, "http://www.response1.com");
expect(item.media.responses.last, "http://www.response2.com");
expect(item.media.responses.first, 'http://www.response1.com');
expect(item.media.responses.last, 'http://www.response2.com');

expect(item.media.backLinks.length, 2);
expect(item.media.backLinks.first, "http://www.backlink1.com");
expect(item.media.backLinks.last, "http://www.backlink2.com");
expect(item.media.backLinks.first, 'http://www.backlink1.com');
expect(item.media.backLinks.last, 'http://www.backlink2.com');

expect(item.media.status.state, "active");
expect(item.media.status.state, 'active');
expect(item.media.status.reason, null);

expect(item.media.prices.length, 2);
expect(item.media.prices.first.price, 19.99);
expect(item.media.prices.first.type, "rent");
expect(item.media.prices.first.type, 'rent');
expect(
item.media.prices.first.info, "http://www.dummy.jp/package_info.html");
expect(item.media.prices.first.currency, "EUR");
item.media.prices.first.info, 'http://www.dummy.jp/package_info.html');
expect(item.media.prices.first.currency, 'EUR');

expect(item.media.license.type, "text/html");
expect(item.media.license.href, "http://www.licensehost.com/license");
expect(item.media.license.value, " Sample license for a video");
expect(item.media.license.type, 'text/html');
expect(item.media.license.href, 'http://www.licensehost.com/license');
expect(item.media.license.value, ' Sample license for a video');

expect(item.media.peerLink.type, "application/x-bittorrent");
expect(item.media.peerLink.href, "http://www.foo.org/sampleFile.torrent");
expect(item.media.peerLink.value, "");
expect(item.media.peerLink.type, 'application/x-bittorrent');
expect(item.media.peerLink.href, 'http://www.foo.org/sampleFile.torrent');
expect(item.media.peerLink.value, '');

expect(item.media.rights.status, "official");
expect(item.media.rights.status, 'official');

expect(item.media.scenes.length, 2);
expect(item.media.scenes.first.title, "sceneTitle1");
expect(item.media.scenes.first.description, "sceneDesc1");
expect(item.media.scenes.first.startTime, "00:15");
expect(item.media.scenes.first.endTime, "00:45");
expect(item.media.scenes.first.title, 'sceneTitle1');
expect(item.media.scenes.first.description, 'sceneDesc1');
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();
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");
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, DateTime.utc(2000, 1, 1, 12));
expect(feed.dc.created, DateTime.utc(2000, 1, 1, 13));
expect(feed.dc.modified, DateTime.utc(2000, 1, 1, 14));
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, DateTime.utc(2000, 1, 2, 12));
expect(feed.items.first.dc.created, DateTime.utc(2000, 1, 2, 13));
expect(feed.items.first.dc.modified, DateTime.utc(2000, 1, 2, 14));
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');
});

test("parse RSS-Empty.xml", () {
var xmlString = File("test/xml/RSS-Empty.xml").readAsStringSync();
test('parse RSS-Empty.xml', () {
var xmlString = File('test/xml/RSS-Empty.xml').readAsStringSync();

var feed = RssFeed.parse(xmlString);

@@ -310,58 +316,96 @@ void main() {
expect(feed.items.first.content, null);
});

test("parse RSS-Itunes.xml", () {
var xmlString = File("test/xml/RSS-Itunes.xml").readAsStringSync();
test('parse RSS-Itunes.xml', () {
var xmlString = File('test/xml/RSS-Itunes.xml').readAsStringSync();

var feed = RssFeed.parse(xmlString);

expect(feed.itunes.author, "Changelog Media");
expect(feed.itunes.summary, "Foo");
expect(feed.itunes.author, 'Changelog Media');
expect(feed.itunes.summary, 'Foo');
expect(feed.itunes.explicit, false);
expect(feed.itunes.image.href,
"https://cdn.changelog.com/uploads/covers/go-time-original.png?v=63725770357");
'https://cdn.changelog.com/uploads/covers/go-time-original.png?v=63725770357');
expect(feed.itunes.keywords,
"go,golang,open source,software,development".split(","));
expect(feed.itunes.owner.name, "Changelog Media");
expect(feed.itunes.owner.email, "editors@changelog.com");
'go,golang,open source,software,development'.split(','));
expect(feed.itunes.owner.name, 'Changelog Media');
expect(feed.itunes.owner.email, 'editors@changelog.com');
expect(
Set.from([
feed.itunes.categories[0].category,
feed.itunes.categories[1].category
]),
["Technology", "Foo"]);
['Technology', 'Foo']);
for (var category in feed.itunes.categories) {
switch (category.category) {
case "Foo":
expect(category.subCategories, ["Bar", "Baz"]);
case 'Foo':
expect(category.subCategories, ['Bar', 'Baz']);
break;
case "Technology":
expect(category.subCategories, ["Software How-To", "Tech News"]);
case 'Technology':
expect(category.subCategories, ['Software How-To', 'Tech News']);
break;
}
}
expect(feed.itunes.title, "Go Time");
expect(feed.itunes.type, RssItunesType.serial);
expect(feed.itunes.newFeedUrl, "wubawuba");
expect(feed.itunes.title, 'Go Time');
expect(feed.itunes.type, ItunesType.serial);
expect(feed.itunes.newFeedUrl, 'wubawuba');
expect(feed.itunes.block, true);
expect(feed.itunes.complete, true);

var item = feed.items[0];
expect(item.itunes.episodeType, RssItunesEpisodeType.full);
expect(item.itunes.episodeType, ItunesEpisodeType.full);
expect(item.itunes.episode, 1);
expect(item.itunes.season, 1);
expect(item.itunes.image.href,
"https://cdn.changelog.com/uploads/covers/go-time-original.png?v=63725770357");
'https://cdn.changelog.com/uploads/covers/go-time-original.png?v=63725770357');
expect(item.itunes.duration, Duration(minutes: 32, seconds: 30));
expect(item.itunes.explicit, false);
expect(item.itunes.keywords,
"go,golang,open source,software,development".split(","));
expect(item.itunes.subtitle, "with Erik, Carlisia, and Brian");
expect(item.itunes.summary, "Foo");
'go,golang,open source,software,development'.split(','));
expect(item.itunes.subtitle, 'with Erik, Carlisia, and Brian');
expect(item.itunes.summary, 'Foo');
expect(item.itunes.author,
"Erik St. Martin, Carlisia Pinto, and Brian Ketelsen");
'Erik St. Martin, Carlisia Pinto, and Brian Ketelsen');
expect(item.itunes.explicit, false);
expect(item.itunes.title, "awesome title");
expect(item.itunes.title, 'awesome title');
expect(item.itunes.block, false);
});

test('parse RSS-RDF.xml', () {
var xmlString = File('test/xml/RSS-RDF.xml').readAsStringSync();

var feed = RssFeed.parse(xmlString);

expect(feed.title, 'Mozilla Dot Org');
expect(feed.link, 'http://www.mozilla.org');
expect(feed.description, 'the Mozilla Organization web site');
expect(feed.image.title, 'Mozilla');
expect(feed.image.url, 'http://www.mozilla.org/images/moz.gif');
expect(feed.image.link, 'http://www.mozilla.org');
expect(feed.items.length, 5);
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');
});
}

+ 1
- 1
test/xml/Atom.xml Zobrazit soubor

@@ -35,7 +35,7 @@
<entry>
<id>foo-bar-entry-id-1</id>
<title>Foo bar item 1</title>
<updated>2018-04-06T13:02:47Z</updated>
<updated>2018-04-06T13:02:40Z</updated>
<author>
<name>Ellie</name>
<uri>http://foo.bar.news/people/ellie</uri>


+ 5
- 1
test/xml/RSS-DC.xml Zobrazit soubor

@@ -9,6 +9,8 @@
<dc:publisher>publisher</dc:publisher>
<dc:contributor>contributor</dc:contributor>
<dc:date>2000-01-01T12:00+00:00</dc:date>
<dc:created>2000-01-01T13:00+00:00</dc:created>
<dc:modified>2000-01-01T14:00+00:00</dc:modified>
<dc:type>type</dc:type>
<dc:format>format</dc:format>
<dc:identifier>identifier</dc:identifier>
@@ -24,7 +26,9 @@
<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:date>2000-01-02T12:00+00:00</dc:date>
<dc:created>2000-01-02T13:00+00:00</dc:created>
<dc:modified>2000-01-02T14:00+00:00</dc:modified>
<dc:type>type</dc:type>
<dc:format>format</dc:format>
<dc:identifier>identifier</dc:identifier>


+ 2
- 5
test/xml/RSS-Itunes.xml Zobrazit soubor

@@ -45,12 +45,9 @@
<itunes:keywords>go, golang, open source, software, development</itunes:keywords>
<itunes:subtitle>with Erik, Carlisia, and Brian</itunes:subtitle>
<itunes:summary>Foo</itunes:summary>
<dc:creator>
Erik St. Martin, Carlisia Pinto, and Brian Ketelsen
<dc:creator>Erik St. Martin, Carlisia Pinto, and Brian Ketelsen
</dc:creator>
<itunes:author>
Erik St. Martin, Carlisia Pinto, and Brian Ketelsen
</itunes:author>
<itunes:author>Erik St. Martin, Carlisia Pinto, and Brian Ketelsen</itunes:author>
</item>
</channel>
</rss>

+ 35
- 0
test/xml/RSS-RDF.xml Zobrazit soubor

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://channel.netscape.com/rdf/simple/0.9/">
<channel>
<title>Mozilla Dot Org</title>
<link>http://www.mozilla.org</link>
<description>the Mozilla Organization web site</description>
</channel>
<image>
<title>Mozilla</title>
<url>http://www.mozilla.org/images/moz.gif</url>
<link>http://www.mozilla.org</link>
</image>
<item>
<title>New Status Updates</title>
<link>http://www.mozilla.org/status/</link>
</item>
<item>
<title>Bugzilla Reorganized</title>
<link>http://www.mozilla.org/bugs/</link>
</item>
<item>
<title>Mozilla Party, 2.0!</title>
<link>http://www.mozilla.org/party/1999/</link>
</item>
<item>
<title>Unix Platform Parity</title>
<link>http://www.mozilla.org/build/unix.html</link>
</item>
<item>
<title>NPL 1.0M published</title>
<link>http://www.mozilla.org/NPL/NPL-1.0M.html</link>
</item>
</rdf:RDF>

+ 24
- 0
test/xml/RSS-Syndication.xml Zobrazit soubor

@@ -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>

Načítá se…
Zrušit
Uložit