Download NHK English news podcast automatically. XML Parser "spxml" is used. This application requires mpod mother board. See also http://mbed.org/users/geodenx/notebook/mpod/

Dependencies:   BlinkLed HTTPClient EthernetInterface FatFileSystemCpp MSCFileSystem spxml mbed-rtos mbed

Fork of mpod_nhk_english by Satoshi Togawa

Download NHK English news podcast automatically.
XML Parser "spxml" is used.
This application requires mpod mother board.
See also http://mbed.org/users/geodenx/notebook/mpod/

main.cpp

Committer:
togayan
Date:
2012-09-06
Revision:
8:a9541e8897f5
Parent:
7:ad9fcf0e1bc5

File content as of revision 8:a9541e8897f5:

#include "mbed.h"
#include "MSCFileSystem.h"
#include "EthernetInterface.h"
#include "HTTPClient.h"
#include "HTTPFile.h"
#include "BlinkLed.h"
#include "spdomparser.hpp"
#include "spxmlnode.hpp"
#include "spxmlhandle.hpp"

int GetFile(const char *path, const char *url);

EthernetInterface eth;
HTTPClient http;
MSCFileSystem usb("usb");
BlinkLed led3(LED3, 0.02);
BlinkLed led4(LED4, 0.2);
BlinkLed ethGreen(p26, 0.02);
BlinkLed ethYellow(p25, 0.2);
DigitalOut fsusb30s(p9);

const char* rssUrl = "http://www3.nhk.or.jp/rj/podcast/rss/english.xml";
const char* rssPath = "/usb/english.xml";
const char* mp3Path = "/usb/english.mp3";

int main()
{
    printf("\n\n===========================================\n");
    printf("mpod NHK English news Downloader with spxml\n");
    printf("===========================================\n\n");
    
    // Indicate downloading
    led4.startBlink();
    ethYellow.startBlink();
    
    // FSUSB30 switches to HSD1 (mbed)
    printf("USB host was switched to HSD1(mbed).\n\n");
    fsusb30s = 0; // HSD1
    
    // Network setup
    printf("Setup EtherNet with DHCP.\n");
    eth.init(); //Use DHCP
    eth.connect();
    printf("IP Address is %s\n\n", eth.getIPAddress());
    
    // Obtain original lastBuildDate
    char lastBuildDateOriginal[128] = {0};
    {
        FILE * fpOriginal = fopen ( rssPath, "r" );
        if( NULL == fpOriginal ) {
            printf( "cannot not open %s\n", rssPath );
            sprintf(lastBuildDateOriginal, "cannot not open original %s", rssPath );
        }
        else
        {
            fseek(fpOriginal, 0, SEEK_END); // seek to end of file
            unsigned int size = ftell(fpOriginal);
            fseek(fpOriginal, 0, SEEK_SET); // seek to head of file
            
            char * source = NULL;
            source = ( char * ) malloc ( size + 1 );
            fread ( source, size, sizeof ( char ), fpOriginal );
            fclose ( fpOriginal );
            source[ size ] = 0;
            
            SP_XmlDomParser parser;
            parser.append( source, strlen( source ) );
            free( source );
            
            SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() );
            
            SP_XmlCDataNode * lastBuildDateNode = rootHandle.getChild( "channel" ).getChild( "lastBuildDate" ).getChild(0).toCData();
            if( NULL != lastBuildDateNode )
            {
                strcpy(lastBuildDateOriginal, lastBuildDateNode->getText());
            } else {
                sprintf(lastBuildDateOriginal, "Cannot found /rss/channel/lastBuildDate");
            }
        }
    }
    printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
    
    // Download RSS
    GetFile(rssPath, rssUrl);
    
    // Obtain current lastBuildDate 
    char lastBuildDateCurrent[128] = {0};
    char mp3Url[256] = {0};
    char mp3Length[32] = {0};
    {
        FILE * fpCurrent = fopen ( rssPath, "r" );
        if( NULL == fpCurrent ) {
            fsusb30s = 1; // HSD2
            error("No current english.xml in USB memory.\n");
        }
        else
        {
            fseek(fpCurrent, 0, SEEK_END); // seek to end of file
            unsigned int size = ftell(fpCurrent);
            fseek(fpCurrent, 0, SEEK_SET); // seek to head of file
            
            char * source = NULL;
            source = ( char * ) malloc ( size + 1 );
            fread ( source, size, sizeof ( char ), fpCurrent );
            fclose ( fpCurrent );
            source[ size ] = 0;
            
            SP_XmlDomParser parser;
            parser.append( source, strlen( source ) );
            free( source );
            
            SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() );
            
            SP_XmlCDataNode * lastBuildDateNode = rootHandle.getChild( "channel" ).getChild( "lastBuildDate" ).getChild(0).toCData();
            if( NULL != lastBuildDateNode )
            {
                strcpy(lastBuildDateCurrent, lastBuildDateNode->getText());
            } else {
                fsusb30s = 1; // HSD2
                error("No \"lastBuildDate\" element in current RSS.\n");
            }
            
            SP_XmlElementNode * enclosureNode = rootHandle.getChild( "channel" ).getChild( "item" ).getChild("enclosure").toElement();
            if( NULL != enclosureNode )
            {
                strcpy(mp3Url, enclosureNode->getAttrValue("url"));
                strcpy(mp3Length, enclosureNode->getAttrValue("length"));
            } else {
                fsusb30s = 1; // HSD2
                error("No \"lastBuildDate\" element in current RSS.\n");
            }
            
        }
    }
    printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
    
    // Determine the necessity of downloading new MP3.
    bool flgDownloadMp3 = false;
    if ( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0 )
    {
        printf("lastBuildDate (original) == lastBuildDate (current)\n");
        FILE* mp3fp = fopen(mp3Path, "r"); // check an existance of english.mp3
        if (mp3fp != NULL)
        {
            fseek(mp3fp, 0, SEEK_END); // seek to end of file
            if (ftell(mp3fp) != atol(mp3Length))
            {
                printf("MP3 file size is invalid.\n");
                flgDownloadMp3 = true;
            }
            fclose(mp3fp);
        }
        else
        {
            printf("However, no enlish.mp3 in USB memory\n");
            flgDownloadMp3 = true;
        }
    }
    else
    {
        printf("lastBuildDate (original) != lastBuildDate (current)\n");
        flgDownloadMp3 = true;
    }
    
    // Download new MP3
    if(flgDownloadMp3 == true)
    {
        GetFile(mp3Path, mp3Url);
    }
    
    // Wait for the completion of writing to USB Mass Storage Device.
    wait(1);
    
    // FSUSB30 switches to HSD2 (External Device)
    printf("\nUSB host was switched to HSD2(External Device).\n");
    fsusb30s = 1; // HSD2

    // Indicate finish downloading
    led4.finishBlink();
    ethYellow.finishBlink();
    led3.startBlink();
    ethGreen.startBlink();
    
    while(true){}
}

int GetFile(const char *path, const char *url)
{
    printf("Getting %s -> %s\n", url, path);
    
    HTTPFile file(path);
    HTTPResult retGet = http.get(url, &file);
    if (retGet != HTTP_OK)
    {
        fsusb30s = 1; // HSD2
        error("Error in http.get in GetFile(): %d\n", retGet);
    }
    file.clear();
    
    return (0);
}