License text

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER 
 * Copyright  2008, 2010 Oracle and/or its affiliates.  All rights reserved. 
 * Use is subject to license terms.
 * 
 * This file is available and licensed under the following license:
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 
 *   * Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer. 
 *
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 *   * Neither the name of Oracle Corporation nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software 
 *     without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

    

package fxpodcastviewer.feed;

/**
 * @author Raghu Nair
 */
import java.lang.Integer;
import javafx.data.feed.atom.AtomTask;
import javafx.data.feed.atom.Feed;
import javafx.data.feed.FeedTask;
import javafx.data.feed.atom.Entry;
import javafx.data.feed.rss.RssTask;
import javafx.data.feed.rss.Channel;
import javafx.data.feed.rss.Item;
import java.lang.RuntimeException;
import fxpodcastviewer.Main;


public def ATOM = 1;

public def RSS  = 2;


/* Podcast Parser */
public class PodcastParser {

    public var feedInterval:Duration = 30m;
    //RSS/Atom FeedTask associated with it.
    public var feedTask:FeedTask ;


    /* Indicates is parsing done for the current feed*/
    public-read var isDone :Boolean = false on replace {
        if ( isDone and podcastFeed.medias != null and sizeof podcastFeed.medias > 0){
            Main.mainScreen.mediaMeta = podcastFeed.medias[0];
            Main.currentFeed = podcastFeed;
        }
    }

    /* Current Feed */
    public-read var podcastFeed:PodcastFeed;

    /* RSS or Atom Feed Location */
    public-init var location:String on replace {
        FeedValidator{  
            podcastParser: this
            location:location
        }.start()
    }


    /* Indicates Atom or RSS */
    public var type:Integer on replace {

        if ( type == ATOM ){
            feedTask = AtomTask{
                location:location;
                interval:feedInterval;
                onFeed: function(feed:Feed){
                    podcastFeed.title = feed.title.text;
                }

                onEntry: function(entry:Entry){
                    var length:Long ;
                    var mediaURL = null;
                    var apptype = null;
                    var media:PodcastMedia = null;
                    for (link in entry.links){
                        
                        if ( link.type != null and 
                            (link.type.trim().startsWith("audio") or
                            link.type.trim().startsWith("video")) )  {
                            
                            apptype  = link.type;
                        }else {
                            continue;
                        }
                        
                        try {
                            if ( link.length != null and
                                not link.length.trim().equals("")) {
                                length = Long.parseLong(link.length);
                            }else {
                                length = 0;
                            }
                        }catch (e){ length = 0}

                        if ( link.href != null ){
                            
                            mediaURL = link.href;
                            insert
                            (media = PodcastMedia{
                                length:length
                                mediaURL:mediaURL
                                type:apptype })
                            into podcastFeed.medias;
                            
                        }
                        if ( link.title != null and link.title != "") {
                            media.title = link.title;
                        }
                    }
                    if ( media != null ){
                        if ( media.title == null ){
                            media.title = entry.title.text;
                        }
                        media.data =  entry.summary.text;
                    }
                    //Needs to investigate and find out how to get if any artwork attached.
                    media.image = "{__DIR__}ui/desktop/resources/podcast.png";

                    media.pubDate = entry.published.datetime.impl_toRFC822String();
                    media.parentFeed = podcastFeed;
                    if ( sizeof entry.authors > 0 ) {
                        media.publisher = entry.authors[0].name;
                        for ( i in [1..sizeof entry.authors-1] ){
                            media.publisher = "{media.publisher},{entry.authors[i]}";
                        }
                    }
                }
            }
        }else if ( type == RSS ) {
            feedTask = RssTask{
                location:location

                interval:feedInterval

                onChannel:function(channel:Channel){
                    
                    podcastFeed.title = channel.title;
                    podcastFeed.description = channel.description;
                }
                onItem:function(item:Item){
                    
                    var media:PodcastMedia;
                    var enclosure = item.enclosure;
                    if ( enclosure != null and 
                        (enclosure.type.startsWith("audio") or
                        enclosure.type.startsWith("video") ) and 
                        enclosure.url.startsWith("http")) {
                        media = PodcastMedia{
                            mediaURL: enclosure.url
                            type: enclosure.type
                            length: enclosure.length
                        }
                    }else return;
                    media.title = item.title;
                    media.data = item.description;
                    media.pubDate = item.pubDate.impl_toRFC822String();
                    media.publisher = item.author;
                    //Needs to investigate and find out how to get if any artwork attached.
                    media.image = "{__DIR__}ui/desktop/resources/podcast.png";
                    media.parentFeed = podcastFeed;
                    insert  media into podcastFeed.medias;
                }
            }
        }
        if ( feedTask != null ){
            //Create podcast feed for Atom/RSS.
            podcastFeed = PodcastFeed{location:location  feedTask:feedTask}
            feedTask.start();
            feedTask.onDone = function(){
                isDone = true;
            }

        }else {
            if ( type == -1)
                throw new RuntimeException("Not a RSS/Atom Feed - {location}");
        }
    }
}