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

Revision:
0:dfd5cfea7112
Child:
2:531722036c0a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Aug 22 16:00:38 2012 +0000
@@ -0,0 +1,237 @@
+#include "mbed.h"
+#include "MSCFileSystem.h"
+#include "EthernetInterface.h"
+#include "HTTPClient.h"
+#include "HTTPFile.h"
+#include "BlinkLed.h"
+#include "tinyxml2.h"
+
+using namespace tinyxml2;
+
+int GetFile(const char *path, const char *url);
+int addNewLine(const char* dstPath, const char* srcPath);
+int summarizeRss(const char* dstPath, const char* srcPath);
+
+EthernetInterface eth;
+HTTPClient http;
+MSCFileSystem usb("usb");
+BlinkLed led1(LED1, 0.02);
+BlinkLed led2(LED2, 0.2);
+BlinkLed ethGreen(p26, 0.02);
+BlinkLed ethYellow(p25, 0.2);
+DigitalOut fsusb30s(p9);
+Timer timer;
+
+/***** 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* tempPath     = "/usb/temp.xml";
+const char* summaryPath  = "/usb/summary.xml";
+
+int main()
+{
+    printf("\n\n================================\n");
+    printf("mpod Picasa Photo frame\n");
+    printf("================================\n\n");
+    
+    // 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();
+    
+    // Obtain original lastBuildDate
+    char lastBuildDateOriginal[32] = {0};
+    {
+        XMLDocument docOriginal;
+        if(XML_SUCCESS != docOriginal.LoadFile(summaryPath))
+        {
+            strcpy(lastBuildDateOriginal, "No original summary.xml in USB memory");
+        }
+        else
+        {
+            XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
+            if(NULL == lastBuildDateOriginalElement)
+            {
+                strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" element in original RSS");
+            }
+            else
+            {
+                strcpy(lastBuildDateOriginal, lastBuildDateOriginalElement->GetText());
+            }
+        }
+    }
+    printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
+    
+    // Download Album
+    GetFile(albumRssPath, albumRssUrl);
+    
+    // Summarize RSS
+    addNewLine(tempPath, albumRssPath);
+    summarizeRss(summaryPath, tempPath);
+    
+    // Obtain current lastBuildDate 
+    char lastBuildDateCurrent[32] = {0};
+    
+    XMLDocument docCurrent;
+    if(XML_SUCCESS != docCurrent.LoadFile(summaryPath))
+    {
+        fsusb30s = 1; // HSD2
+        error("No current summary.xml in USB memory.\n");
+    }
+    
+    XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
+    if(NULL == lastBuildDateCurrentElement)
+    {
+        fsusb30s = 1; // HSD2
+        error("No \"lastBuildDate\" element in current RSS.\n");
+    }
+    strcpy(lastBuildDateCurrent, lastBuildDateCurrentElement->GetText());
+    printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
+    
+    
+    char photoUrl[256] = {0};
+    char photoPath[32] = {0};
+    int photoNo = 1;
+    XMLElement* itemElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item");
+    if(NULL == itemElement)
+    {
+        fsusb30s = 1; // HSD2
+        error("No \"enclosure\" element in current RSS.\n");
+    }
+    strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
+    sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo);
+    GetFile(photoPath, photoUrl);
+    ++photoNo;
+
+    while( (itemElement = itemElement->NextSiblingElement( "item" ) ) != NULL )
+    {
+        strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
+        sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo);
+        GetFile(photoPath, photoUrl);
+        ++photoNo;
+    }
+    
+    // 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
+
+    // blink LED
+    led1.startBlink();
+    ethGreen.startBlink();
+    
+    while(true){}
+}
+
+int GetFile(const char *path, const char *url)
+{
+    led2.startBlink();
+    ethYellow.startBlink();
+    printf("\nGetting %s\n", url);
+    
+    timer.stop();
+    timer.reset();
+    timer.start();
+    
+    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();
+    
+    timer.stop();
+    printf("timer.read_ms(): %d\n", timer.read_ms());
+    
+    led2.finishBlink();
+    ethYellow.finishBlink();
+    return (0);
+}
+
+int addNewLine(const char* dstPath, const char* srcPath)
+{
+    FILE* fpSrc = fopen(srcPath, "r");
+    if (fpSrc == NULL)
+    {
+        return -1;
+    }
+    
+    FILE* fpDst = fopen(dstPath, "w");
+    if (fpDst == NULL)
+    {
+        return -1;
+    }
+    
+    int src;
+    int previous = '\0';
+    while( (src = fgetc(fpSrc)) != EOF )
+    {
+        if(previous == '>' && src == '<')
+        {
+            fputc('\n', fpDst);
+        }
+        fputc(src, fpDst);
+        previous = src;
+    }
+    
+    fclose(fpDst);
+    fclose(fpSrc);
+    
+    return 0;
+}
+
+int summarizeRss(const char* dstPath, const char* srcPath)
+{
+    FILE* fpSrc = fopen(srcPath, "r");
+    if (fpSrc == NULL)
+    {
+        return -1;
+    }
+    
+    FILE* fpDst = fopen(dstPath, "w");
+    if (fpDst == NULL)
+    {
+        return -1;
+    }
+    
+    char* ptn[] =
+    {
+        "<?xml",
+        "<rss",
+        "<channel",
+        "<lastBuildDate",
+        "<item",
+        "<enclosure",
+        "</item",
+        "</channel",
+        "</rss"
+    };
+    int ptnSize = sizeof(ptn) / sizeof(char*);
+    
+    char buff[1024] = {0};
+    while( fgets(buff, 1024, fpSrc) != NULL )
+    {
+        for(int i = 0; i < ptnSize; ++i)
+        {
+            if( strncmp(buff, ptn[i], strlen(ptn[i])) == 0 )
+            {
+                fputs(buff, fpDst);
+                break;
+            }
+        }
+    }
+    
+    fclose(fpDst);
+    fclose(fpSrc);
+    
+    return 0;
+}