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:
5:66c3398a14c9
Parent:
4:f2d619e67d44
Child:
6:83383116c88a
--- a/main.cpp	Fri Aug 24 17:39:24 2012 +0000
+++ b/main.cpp	Tue Aug 28 14:41:17 2012 +0000
@@ -4,14 +4,11 @@
 #include "HTTPClient.h"
 #include "HTTPFile.h"
 #include "BlinkLed.h"
-#include "tinyxml2.h"
-
-using namespace tinyxml2;
+#include <cstring>
 
 int GetFile(const char *path, const char *url);
-int addNewLine(const char* dstPath, const char* srcPath);
 int summarizeRss(const char* dstPath, const char* srcPath);
-int removePhotos();
+int removeContents(const char* url);
 const char* getExtensionFromUrl(const char* url);
 
 EthernetInterface eth;
@@ -22,20 +19,20 @@
 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";
+const char* summaryPath  = "/usb/summary.txt";
+const char* contentsFolder = "/usb/DCIM";
 
 int main()
 {
-    printf("\n\n================================\n");
-    printf("mpod Picasa Photo frame\n");
-    printf("================================\n\n");
+    puts("");
+    puts("================================");
+    puts("mpod Picasa Photo frame");
+    puts("================================\n");
     
     // Check albumRssUrl
     if(NULL != strstr(albumRssUrl, "*****"))
@@ -47,35 +44,38 @@
         error("[ERROR] Please specify the URL of the RSS in \"HTTP\" format.\n");
     }
     
+    // Indicate downloading
+    led2.startBlink();
+    ethYellow.startBlink();
+        
     // FSUSB30 switches to HSD1 (mbed)
-    printf("USB host was switched to HSD1(mbed).\n\n");
+    puts("USB host was switched to HSD1(mbed).\n");
     fsusb30s = 0; // HSD1
     
     // Network setup
-    printf("Setup EtherNet with DHCP.\n");
+    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[32] = {0};
+    char lastBuildDateOriginal[40] = {0};
+    FILE* fpOriginal = fopen(summaryPath, "r");
+    if (fpOriginal == NULL)
     {
-        XMLDocument docOriginal;
-        if(XML_SUCCESS != docOriginal.LoadFile(summaryPath))
+        strcpy(lastBuildDateOriginal, "No summary.txt in USB memory");
+    }
+    else
+    {
+        if(fgets(lastBuildDateOriginal, 40, fpOriginal) == NULL)
         {
-            strcpy(lastBuildDateOriginal, "No original summary.xml in USB memory");
+            strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" in RSS");
         }
         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());
-            }
+            lastBuildDateOriginal[strlen(lastBuildDateOriginal) - 1] = '\0';
         }
+        fclose(fpOriginal);
     }
     printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
     
@@ -83,35 +83,36 @@
     GetFile(albumRssPath, albumRssUrl);
     
     // Summarize RSS
-    addNewLine(tempPath, albumRssPath);
-    summarizeRss(summaryPath, tempPath);
+    summarizeRss(summaryPath, albumRssPath);
     
-    // Obtain current lastBuildDate 
-    char lastBuildDateCurrent[32] = {0};
-    
-    XMLDocument docCurrent;
-    if(XML_SUCCESS != docCurrent.LoadFile(summaryPath))
+    // Obtain current lastBuildDate
+    char lastBuildDateCurrent[40] = {0};
+    FILE* fpCurrent = fopen(summaryPath, "r");
+    if (fpCurrent == NULL)
     {
         fsusb30s = 1; // HSD2
-        error("No current summary.xml in USB memory.\n");
+        error("No current summary.txt in USB memory.\n");
     }
-    
-    XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
-    if(NULL == lastBuildDateCurrentElement)
+    else
     {
-        fsusb30s = 1; // HSD2
-        error("No \"lastBuildDate\" element in current RSS.\n");
+        if(fgets(lastBuildDateCurrent, 40, fpCurrent) == NULL)
+        {
+            fsusb30s = 1; // HSD2
+            error("No \"lastBuildDate\" element in current RSS.\n");
+        }
+        else
+        {
+            lastBuildDateCurrent[strlen(lastBuildDateCurrent) - 1] = '\0';
+        }
     }
-    strcpy(lastBuildDateCurrent, lastBuildDateCurrentElement->GetText());
     printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
     
-    
     // Determine the necessity of downloading new Photos.
     bool flgDownloadPhoto = false;
     if ( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0 )
     {
-        printf("lastBuildDate (original) == lastBuildDate (current)\n");
-        if(NULL == opendir("/usb/DCIM")) // check an existance of DCIM folder
+        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;
@@ -124,50 +125,41 @@
     }
     else
     {
-        printf("lastBuildDate (original) != lastBuildDate (current)\n");
+        puts("lastBuildDate (original) != lastBuildDate (current)");
         flgDownloadPhoto = true;
     }
     
     // Download new Photos
     if(flgDownloadPhoto)
     {
-        if(removePhotos() < 0)
+        if(removeContents(contentsFolder) < 0)
         {
-            mkdir("/usb/DCIM", 0777);
+            mkdir(contentsFolder, 0777);
         }
     
-        char photoUrl[256] = {0};
-        char photoPath[32] = {0};
+        char photoUrl[128] = {0};
+        char photoPath[24] = {0};
         int photoNo = 1;
-        XMLElement* itemElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item");
-        if(NULL == itemElement)
+        while(fgets(photoUrl, 128, fpCurrent) != NULL)
         {
-            fsusb30s = 1; // HSD2
-            error("No \"enclosure\" element in current RSS.\n");
-        }
-        strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
-        const char* extension = getExtensionFromUrl(photoUrl);
-        sprintf(photoPath, "/usb/DCIM/%08d.%s", photoNo, extension);
-        GetFile(photoPath, photoUrl);
-        ++photoNo;
-    
-        while( (itemElement = itemElement->NextSiblingElement( "item" ) ) != NULL )
-        {
-            strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
-            sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo);
+            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)
-    printf("\nUSB host was switched to HSD2(External Device).\n");
+    puts("\nUSB host was switched to HSD2(External Device).\n");
     fsusb30s = 1; // HSD2
 
-    // blink LED
+    // Indicate finish downloading
+    led2.finishBlink();
+    ethYellow.finishBlink();
     led1.startBlink();
     ethGreen.startBlink();
     
@@ -176,13 +168,7 @@
 
 int GetFile(const char *path, const char *url)
 {
-    led2.startBlink();
-    ethYellow.startBlink();
-    printf("\nGetting %s -> %s\n", url, path);
-    
-    timer.stop();
-    timer.reset();
-    timer.start();
+    printf("Getting %s -> %s\n", url, path);
     
     HTTPFile file(path);
     HTTPResult retGet = http.get(url, &file);
@@ -193,16 +179,13 @@
     }
     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)
+int summarizeRss(const char* dstPath, const char* srcPath)
 {
+    puts("Summarizing RSS.");
+    
     FILE* fpSrc = fopen(srcPath, "r");
     if (fpSrc == NULL)
     {
@@ -212,19 +195,33 @@
     FILE* fpDst = fopen(dstPath, "w");
     if (fpDst == NULL)
     {
+        fclose(fpSrc);
         return -1;
     }
     
-    int src;
+    char buff[1024] = {0};
+    char* buffPos = buff;
+    
+    int present;
     int previous = '\0';
-    while( (src = fgetc(fpSrc)) != EOF )
+    while( (present = fgetc(fpSrc)) != EOF )
     {
-        if(previous == '>' && src == '<')
+        if(previous == '>' && present == '<')
         {
-            fputc('\n', fpDst);
+            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;
         }
-        fputc(src, fpDst);
-        previous = src;
+        *buffPos++ = present;
+        previous = present;
     }
     
     fclose(fpDst);
@@ -233,62 +230,15 @@
     return 0;
 }
 
-int summarizeRss(const char* dstPath, const char* srcPath)
+int removeContents(const char* dirName)
 {
-    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;
-}
-
-int removePhotos()
-{
-    if(DirHandle* dir = opendir("/usb/DCIM"))
+    if(DirHandle* dir = opendir(dirName))
     {
         int ret = 0;
         while(struct dirent* ent = dir->readdir())
         {
             char filename[32] = {0};
-            sprintf(filename, "/usb/DCIM/%s", ent->d_name);
+            sprintf(filename, "%s/%s", dirName, ent->d_name);
             printf("remove %s\n", filename);
             remove(filename);
             ++ret;