summaryrefslogtreecommitdiffstats
path: root/js/service/OPMLParser.js
blob: 80ddb8a304c9e5fef70821ae5a3d5fd3971393cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * ownCloud - News
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Bernhard Posselt <dev@bernhard-posselt.com>
 * @copyright Bernhard Posselt 2014
 */
app.service('OPMLParser', function () {
    'use strict';

    var parseOutline = function (outline) {
        var url = outline.attr('xmlUrl') || outline.attr('htmlUrl');
        var name = outline.attr('title') || outline.attr('text') || url;

        // folder
        if (url === undefined) {
            return {
                type: 'folder',
                name: name,
                feeds: []
            };

            // feed
        } else {
            return {
                type: 'feed',
                name: name,
                url: url
            };
        }
    };

    // there is only one level, so feeds in a folder in a folder should be
    // attached to the root folder
    var recursivelyParse = function (level, root, firstLevel) {
        for (var i = 0; i < level.length; i += 1) {
            var outline = $(level[i]);

            var entry = parseOutline(outline);

            if (entry.type === 'feed') {
                root.feeds.push(entry);
            } else {

                // only first level should append folders
                if (firstLevel) {
                    recursivelyParse(outline.children('outline'), entry, false);
                    root.folders.push(entry);
                } else {
                    recursivelyParse(outline.children('outline'), root, false);
                }
            }
        }

        return root;
    };

    this.parse = function (xml) {
        xml = $.parseXML(xml);
        var firstLevel = $(xml).find('body > outline');

        var root = {
            'feeds': [],
            'folders': []
        };

        var parsedResult = recursivelyParse(firstLevel, root, true);

        // merge folders with duplicate names
        var folders = {};
        parsedResult.folders.forEach(function (folder) {
            if (folders[folder.name] === undefined) {
                folders[folder.name] = folder;
            } else {
                folders[folder.name].feeds = folders[folder.name]
                    .feeds.concat(folder.feeds);
            }
        });

        return {
            'feeds': parsedResult.feeds,
            'folders': Object.keys(folders).map(function (key) {
                return folders[key];
            })
        };

    };

});