Download picasa web albums photos automatically. This application requires mpod mother board. See also http://mbed.org/users/geodenx/notebook/mpod/

Dependencies:   BlinkLed HTTPClient EthernetInterface FatFileSystemCpp MSCFileSystem mbed-rtos mbed

Download picasa web albums photos automatically.
This application requires mpod mother board.

Picasaウェブアルバムから、自動的に写真をダウンロードして、ディジタルフォトフレームに表示します。
動作させるには mpod マザーボード が必要です。
プログラムの中で、ご自分のアルバムのRSSファイルへのURLを指定してからご利用下さい。

album description edit information description

main.cpp

Committer:
togayan
Date:
2012-09-01
Revision:
6:83383116c88a
Parent:
5:66c3398a14c9

File content as of revision 6:83383116c88a:

#include "mbed.h"
#include "MSCFileSystem.h"
#include "EthernetInterface.h"
#include "HTTPClient.h"
#include "HTTPFile.h"
#include "BlinkLed.h"
#include <cstring>

int GetFile(const char *path, const char *url);
int summarizeRss(const char* dstPath, const char* srcPath);
int removeContents(const char* url);
const char* getExtensionFromUrl(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);

/***** Please specify "albumRssUrl" *****/
const char* albumRssUrl  = "http://picasaweb.google.com/data/feed/base/user/*****/albumid/*****?alt=rss&kind=photo&authkey=*****&hl=ja";

const char* albumRssPath = "/usb/album.xml";
const char* summaryPath  = "/usb/summary.txt";
const char* contentsFolder = "/usb/DCIM";

int main()
{
    puts("");
    puts("================================");
    puts("mpod Picasa Photo frame");
    puts("================================\n");
    
    // Check albumRssUrl
    if(NULL != strstr(albumRssUrl, "*****"))
    {
        error("[ERROR] Please specify the RSS of YOUR album to \"albumRssUrl\" in the firmware.\n");   
    }
    if(NULL != strstr(albumRssUrl, "https"))
    {
        error("[ERROR] Please specify the URL of the RSS in \"HTTP\" format.\n");
    }
    
    // Indicate downloading
    led4.startBlink();
    ethYellow.startBlink();
        
    // FSUSB30 switches to HSD1 (mbed)
    puts("USB host was switched to HSD1(mbed).\n");
    fsusb30s = 0; // HSD1
    
    // Network setup
    puts("Setup EtherNet with DHCP.");
    eth.init(); //Use DHCP
    eth.connect();
    printf("IP Address is %s\n\n", eth.getIPAddress());
    
    // Obtain original lastBuildDate
    char lastBuildDateOriginal[40] = {0};
    FILE* fpOriginal = fopen(summaryPath, "r");
    if (fpOriginal == NULL)
    {
        strcpy(lastBuildDateOriginal, "No summary.txt in USB memory");
    }
    else
    {
        if(fgets(lastBuildDateOriginal, 40, fpOriginal) == NULL)
        {
            strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" in RSS");
        }
        else
        {
            lastBuildDateOriginal[strlen(lastBuildDateOriginal) - 1] = '\0';
        }
        fclose(fpOriginal);
    }
    printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
    
    // Download Album
    GetFile(albumRssPath, albumRssUrl);
    
    // Summarize RSS
    summarizeRss(summaryPath, albumRssPath);
    
    // Obtain current lastBuildDate
    char lastBuildDateCurrent[40] = {0};
    FILE* fpCurrent = fopen(summaryPath, "r");
    if (fpCurrent == NULL)
    {
        fsusb30s = 1; // HSD2
        error("No current summary.txt in USB memory.\n");
    }
    else
    {
        if(fgets(lastBuildDateCurrent, 40, fpCurrent) == NULL)
        {
            fsusb30s = 1; // HSD2
            error("No \"lastBuildDate\" element in current RSS.\n");
        }
        else
        {
            lastBuildDateCurrent[strlen(lastBuildDateCurrent) - 1] = '\0';
        }
    }
    printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
    
    // Determine the necessity of downloading new Photos.
    bool flgDownloadPhoto = false;
    if ( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0 )
    {
        puts("lastBuildDate (original) == lastBuildDate (current)");
        if(NULL == opendir(contentsFolder)) // check an existance of DCIM folder
        {
            printf("However, no DCIM folder in USB memory\n");
            flgDownloadPhoto = true;
        }
        else
        {
            //Should be checked whether files exist.
            flgDownloadPhoto = false;
        }
    }
    else
    {
        puts("lastBuildDate (original) != lastBuildDate (current)");
        flgDownloadPhoto = true;
    }
    
    // Download new Photos
    if(flgDownloadPhoto)
    {
        if(removeContents(contentsFolder) < 0)
        {
            mkdir(contentsFolder, 0777);
        }
    
        char photoUrl[128] = {0};
        char photoPath[24] = {0};
        int photoNo = 1;
        while(fgets(photoUrl, 128, fpCurrent) != NULL)
        {
            photoUrl[strlen(photoUrl) - 1] = '\0';
            sprintf(photoPath, "%s/%08d.%s", contentsFolder, photoNo, getExtensionFromUrl(photoUrl));
            GetFile(photoPath, photoUrl);
            ++photoNo;
        }
    }
    fclose(fpCurrent);
    
    // Wait for the completion of writing to USB Mass Storage Device.
    wait(1);
    
    // FSUSB30 switches to HSD2 (External Device)
    puts("\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);
}

int summarizeRss(const char* dstPath, const char* srcPath)
{
    puts("Summarizing RSS.");
    
    FILE* fpSrc = fopen(srcPath, "r");
    if (fpSrc == NULL)
    {
        return -1;
    }
    
    FILE* fpDst = fopen(dstPath, "w");
    if (fpDst == NULL)
    {
        fclose(fpSrc);
        return -1;
    }
    
    char buff[1024] = {0};
    char* buffPos = buff;
    
    int present;
    int previous = '\0';
    while( (present = fgetc(fpSrc)) != EOF )
    {
        if(previous == '>' && present == '<')
        {
            if( strncmp(buff, "<lastBuildDate", 14) == 0 )
            {
                *strchr(buff + 15, '<') = '\0';
                fprintf(fpDst, "%s\n", buff + 15);
            }
            else if( strncmp(buff, "<enclosure", 10) == 0 )
            {
                *strchr(buff + 34, '\'') = '\0';
                fprintf(fpDst, "%s\n", buff + 34);
            }
            buffPos = buff;
        }
        *buffPos++ = present;
        previous = present;
    }
    
    fclose(fpDst);
    fclose(fpSrc);
    
    return 0;
}

int removeContents(const char* dirName)
{
    if(DirHandle* dir = opendir(dirName))
    {
        int ret = 0;
        while(struct dirent* ent = dir->readdir())
        {
            char filename[32] = {0};
            sprintf(filename, "%s/%s", dirName, ent->d_name);
            printf("remove %s\n", filename);
            remove(filename);
            ++ret;
        }
        return ret;
    }
    else
    {
        return -1;
    }
}

const char* getExtensionFromUrl(const char* url)
{
    const char* tail = url;
    while('\0' != *tail)
    {
        ++tail;
    }
    
    for(const char* p = tail; p >= url; --p)
    {
        if ('/' == *p)
        {
            return tail;
        }
        if ( '.' == *p )
        {
            return p+1;
        }
    }
    return tail;
}