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

Committer:
togayan
Date:
Fri Aug 24 16:16:54 2012 +0000
Revision:
3:ffbb2b22099a
Parent:
2:531722036c0a
Child:
4:f2d619e67d44
Even if the DCIM folder does not exist, the photos are downloaded.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
togayan 0:dfd5cfea7112 1 #include "mbed.h"
togayan 0:dfd5cfea7112 2 #include "MSCFileSystem.h"
togayan 0:dfd5cfea7112 3 #include "EthernetInterface.h"
togayan 0:dfd5cfea7112 4 #include "HTTPClient.h"
togayan 0:dfd5cfea7112 5 #include "HTTPFile.h"
togayan 0:dfd5cfea7112 6 #include "BlinkLed.h"
togayan 0:dfd5cfea7112 7 #include "tinyxml2.h"
togayan 0:dfd5cfea7112 8
togayan 0:dfd5cfea7112 9 using namespace tinyxml2;
togayan 0:dfd5cfea7112 10
togayan 0:dfd5cfea7112 11 int GetFile(const char *path, const char *url);
togayan 0:dfd5cfea7112 12 int addNewLine(const char* dstPath, const char* srcPath);
togayan 0:dfd5cfea7112 13 int summarizeRss(const char* dstPath, const char* srcPath);
togayan 2:531722036c0a 14 int removePhotos();
togayan 2:531722036c0a 15 const char* getExtensionFromUrl(const char* url);
togayan 0:dfd5cfea7112 16
togayan 0:dfd5cfea7112 17 EthernetInterface eth;
togayan 0:dfd5cfea7112 18 HTTPClient http;
togayan 0:dfd5cfea7112 19 MSCFileSystem usb("usb");
togayan 0:dfd5cfea7112 20 BlinkLed led1(LED1, 0.02);
togayan 0:dfd5cfea7112 21 BlinkLed led2(LED2, 0.2);
togayan 0:dfd5cfea7112 22 BlinkLed ethGreen(p26, 0.02);
togayan 0:dfd5cfea7112 23 BlinkLed ethYellow(p25, 0.2);
togayan 0:dfd5cfea7112 24 DigitalOut fsusb30s(p9);
togayan 0:dfd5cfea7112 25 Timer timer;
togayan 0:dfd5cfea7112 26
togayan 0:dfd5cfea7112 27 /***** Please specify "albumRssUrl" *****/
togayan 0:dfd5cfea7112 28 const char* albumRssUrl = "http://picasaweb.google.com/data/feed/base/user/*****/albumid/*****?alt=rss&kind=photo&authkey=*****&hl=ja";
togayan 3:ffbb2b22099a 29
togayan 0:dfd5cfea7112 30 const char* albumRssPath = "/usb/album.xml";
togayan 0:dfd5cfea7112 31 const char* tempPath = "/usb/temp.xml";
togayan 0:dfd5cfea7112 32 const char* summaryPath = "/usb/summary.xml";
togayan 0:dfd5cfea7112 33
togayan 0:dfd5cfea7112 34 int main()
togayan 0:dfd5cfea7112 35 {
togayan 0:dfd5cfea7112 36 printf("\n\n================================\n");
togayan 0:dfd5cfea7112 37 printf("mpod Picasa Photo frame\n");
togayan 0:dfd5cfea7112 38 printf("================================\n\n");
togayan 0:dfd5cfea7112 39
togayan 3:ffbb2b22099a 40 // Check albumRssUrl
togayan 3:ffbb2b22099a 41 if(NULL != strstr(albumRssUrl, "*****"))
togayan 3:ffbb2b22099a 42 {
togayan 3:ffbb2b22099a 43 error("[ERROR] Please specify the RSS of YOUR album to \"albumRssUrl\" in the firmware.\n");
togayan 3:ffbb2b22099a 44 }
togayan 3:ffbb2b22099a 45 if(NULL != strstr(albumRssUrl, "https"))
togayan 3:ffbb2b22099a 46 {
togayan 3:ffbb2b22099a 47 error("[ERROR] Please specify the URL of the RSS in \"HTTP\" format.\n");
togayan 3:ffbb2b22099a 48 }
togayan 3:ffbb2b22099a 49
togayan 0:dfd5cfea7112 50 // FSUSB30 switches to HSD1 (mbed)
togayan 0:dfd5cfea7112 51 printf("USB host was switched to HSD1(mbed).\n\n");
togayan 0:dfd5cfea7112 52 fsusb30s = 0; // HSD1
togayan 0:dfd5cfea7112 53
togayan 0:dfd5cfea7112 54 // Network setup
togayan 0:dfd5cfea7112 55 printf("Setup EtherNet with DHCP.\n");
togayan 0:dfd5cfea7112 56 eth.init(); //Use DHCP
togayan 0:dfd5cfea7112 57 eth.connect();
togayan 0:dfd5cfea7112 58
togayan 0:dfd5cfea7112 59 // Obtain original lastBuildDate
togayan 0:dfd5cfea7112 60 char lastBuildDateOriginal[32] = {0};
togayan 0:dfd5cfea7112 61 {
togayan 0:dfd5cfea7112 62 XMLDocument docOriginal;
togayan 0:dfd5cfea7112 63 if(XML_SUCCESS != docOriginal.LoadFile(summaryPath))
togayan 0:dfd5cfea7112 64 {
togayan 0:dfd5cfea7112 65 strcpy(lastBuildDateOriginal, "No original summary.xml in USB memory");
togayan 0:dfd5cfea7112 66 }
togayan 0:dfd5cfea7112 67 else
togayan 0:dfd5cfea7112 68 {
togayan 0:dfd5cfea7112 69 XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
togayan 0:dfd5cfea7112 70 if(NULL == lastBuildDateOriginalElement)
togayan 0:dfd5cfea7112 71 {
togayan 0:dfd5cfea7112 72 strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" element in original RSS");
togayan 0:dfd5cfea7112 73 }
togayan 0:dfd5cfea7112 74 else
togayan 0:dfd5cfea7112 75 {
togayan 0:dfd5cfea7112 76 strcpy(lastBuildDateOriginal, lastBuildDateOriginalElement->GetText());
togayan 0:dfd5cfea7112 77 }
togayan 0:dfd5cfea7112 78 }
togayan 0:dfd5cfea7112 79 }
togayan 0:dfd5cfea7112 80 printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
togayan 0:dfd5cfea7112 81
togayan 0:dfd5cfea7112 82 // Download Album
togayan 0:dfd5cfea7112 83 GetFile(albumRssPath, albumRssUrl);
togayan 0:dfd5cfea7112 84
togayan 0:dfd5cfea7112 85 // Summarize RSS
togayan 0:dfd5cfea7112 86 addNewLine(tempPath, albumRssPath);
togayan 0:dfd5cfea7112 87 summarizeRss(summaryPath, tempPath);
togayan 0:dfd5cfea7112 88
togayan 0:dfd5cfea7112 89 // Obtain current lastBuildDate
togayan 0:dfd5cfea7112 90 char lastBuildDateCurrent[32] = {0};
togayan 0:dfd5cfea7112 91
togayan 0:dfd5cfea7112 92 XMLDocument docCurrent;
togayan 0:dfd5cfea7112 93 if(XML_SUCCESS != docCurrent.LoadFile(summaryPath))
togayan 0:dfd5cfea7112 94 {
togayan 0:dfd5cfea7112 95 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 96 error("No current summary.xml in USB memory.\n");
togayan 0:dfd5cfea7112 97 }
togayan 0:dfd5cfea7112 98
togayan 0:dfd5cfea7112 99 XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
togayan 0:dfd5cfea7112 100 if(NULL == lastBuildDateCurrentElement)
togayan 0:dfd5cfea7112 101 {
togayan 0:dfd5cfea7112 102 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 103 error("No \"lastBuildDate\" element in current RSS.\n");
togayan 0:dfd5cfea7112 104 }
togayan 0:dfd5cfea7112 105 strcpy(lastBuildDateCurrent, lastBuildDateCurrentElement->GetText());
togayan 0:dfd5cfea7112 106 printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
togayan 0:dfd5cfea7112 107
togayan 3:ffbb2b22099a 108
togayan 3:ffbb2b22099a 109 // Determine the necessity of downloading new Photos.
togayan 3:ffbb2b22099a 110 bool flgDownloadPhoto = false;
togayan 3:ffbb2b22099a 111 if ( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0 )
togayan 3:ffbb2b22099a 112 {
togayan 3:ffbb2b22099a 113 printf("lastBuildDate (original) == lastBuildDate (current)\n");
togayan 3:ffbb2b22099a 114 if(DirHandle* dir = opendir("/usb/DCIM")) // check an existance of DCIM folder
togayan 3:ffbb2b22099a 115 {
togayan 3:ffbb2b22099a 116 printf("However, no DCIM folder in USB memory\n");
togayan 3:ffbb2b22099a 117 flgDownloadPhoto = true;
togayan 3:ffbb2b22099a 118 }
togayan 3:ffbb2b22099a 119 else
togayan 3:ffbb2b22099a 120 {
togayan 3:ffbb2b22099a 121 //Should be checked whether files exist.
togayan 3:ffbb2b22099a 122 flgDownloadPhoto = false;
togayan 3:ffbb2b22099a 123 }
togayan 3:ffbb2b22099a 124 }
togayan 3:ffbb2b22099a 125 else
togayan 0:dfd5cfea7112 126 {
togayan 2:531722036c0a 127 printf("lastBuildDate (original) != lastBuildDate (current)\n");
togayan 3:ffbb2b22099a 128 flgDownloadPhoto = true;
togayan 3:ffbb2b22099a 129 }
togayan 3:ffbb2b22099a 130
togayan 3:ffbb2b22099a 131 // Download new Photos
togayan 3:ffbb2b22099a 132 if(flgDownloadPhoto)
togayan 3:ffbb2b22099a 133 {
togayan 2:531722036c0a 134 if(removePhotos() < 0)
togayan 2:531722036c0a 135 {
togayan 3:ffbb2b22099a 136 mkdir("/usb/DCIM", 0777);
togayan 2:531722036c0a 137 }
togayan 2:531722036c0a 138
togayan 2:531722036c0a 139 char photoUrl[256] = {0};
togayan 2:531722036c0a 140 char photoPath[32] = {0};
togayan 2:531722036c0a 141 int photoNo = 1;
togayan 2:531722036c0a 142 XMLElement* itemElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item");
togayan 2:531722036c0a 143 if(NULL == itemElement)
togayan 2:531722036c0a 144 {
togayan 2:531722036c0a 145 fsusb30s = 1; // HSD2
togayan 2:531722036c0a 146 error("No \"enclosure\" element in current RSS.\n");
togayan 2:531722036c0a 147 }
togayan 0:dfd5cfea7112 148 strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
togayan 2:531722036c0a 149 const char* extension = getExtensionFromUrl(photoUrl);
togayan 2:531722036c0a 150 sprintf(photoPath, "/usb/DCIM/%08d.%s", photoNo, extension);
togayan 0:dfd5cfea7112 151 GetFile(photoPath, photoUrl);
togayan 0:dfd5cfea7112 152 ++photoNo;
togayan 2:531722036c0a 153
togayan 2:531722036c0a 154 while( (itemElement = itemElement->NextSiblingElement( "item" ) ) != NULL )
togayan 2:531722036c0a 155 {
togayan 2:531722036c0a 156 strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
togayan 2:531722036c0a 157 sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo);
togayan 2:531722036c0a 158 GetFile(photoPath, photoUrl);
togayan 2:531722036c0a 159 ++photoNo;
togayan 2:531722036c0a 160 }
togayan 2:531722036c0a 161 }
togayan 0:dfd5cfea7112 162
togayan 0:dfd5cfea7112 163 // Wait for the completion of writing to USB Mass Storage Device.
togayan 0:dfd5cfea7112 164 wait(1);
togayan 0:dfd5cfea7112 165
togayan 0:dfd5cfea7112 166 // FSUSB30 switches to HSD2 (External Device)
togayan 0:dfd5cfea7112 167 printf("\nUSB host was switched to HSD2(External Device).\n");
togayan 0:dfd5cfea7112 168 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 169
togayan 0:dfd5cfea7112 170 // blink LED
togayan 0:dfd5cfea7112 171 led1.startBlink();
togayan 0:dfd5cfea7112 172 ethGreen.startBlink();
togayan 0:dfd5cfea7112 173
togayan 0:dfd5cfea7112 174 while(true){}
togayan 0:dfd5cfea7112 175 }
togayan 0:dfd5cfea7112 176
togayan 0:dfd5cfea7112 177 int GetFile(const char *path, const char *url)
togayan 0:dfd5cfea7112 178 {
togayan 0:dfd5cfea7112 179 led2.startBlink();
togayan 0:dfd5cfea7112 180 ethYellow.startBlink();
togayan 3:ffbb2b22099a 181 printf("\nGetting %s -> %s\n", url, path);
togayan 0:dfd5cfea7112 182
togayan 0:dfd5cfea7112 183 timer.stop();
togayan 0:dfd5cfea7112 184 timer.reset();
togayan 0:dfd5cfea7112 185 timer.start();
togayan 0:dfd5cfea7112 186
togayan 0:dfd5cfea7112 187 HTTPFile file(path);
togayan 0:dfd5cfea7112 188 HTTPResult retGet = http.get(url, &file);
togayan 0:dfd5cfea7112 189 if (retGet != HTTP_OK)
togayan 0:dfd5cfea7112 190 {
togayan 0:dfd5cfea7112 191 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 192 error("Error in http.get in GetFile(): %d\n", retGet);
togayan 0:dfd5cfea7112 193 }
togayan 0:dfd5cfea7112 194 file.clear();
togayan 0:dfd5cfea7112 195
togayan 0:dfd5cfea7112 196 timer.stop();
togayan 0:dfd5cfea7112 197 printf("timer.read_ms(): %d\n", timer.read_ms());
togayan 0:dfd5cfea7112 198
togayan 0:dfd5cfea7112 199 led2.finishBlink();
togayan 0:dfd5cfea7112 200 ethYellow.finishBlink();
togayan 0:dfd5cfea7112 201 return (0);
togayan 0:dfd5cfea7112 202 }
togayan 0:dfd5cfea7112 203
togayan 0:dfd5cfea7112 204 int addNewLine(const char* dstPath, const char* srcPath)
togayan 0:dfd5cfea7112 205 {
togayan 0:dfd5cfea7112 206 FILE* fpSrc = fopen(srcPath, "r");
togayan 0:dfd5cfea7112 207 if (fpSrc == NULL)
togayan 0:dfd5cfea7112 208 {
togayan 0:dfd5cfea7112 209 return -1;
togayan 0:dfd5cfea7112 210 }
togayan 0:dfd5cfea7112 211
togayan 0:dfd5cfea7112 212 FILE* fpDst = fopen(dstPath, "w");
togayan 0:dfd5cfea7112 213 if (fpDst == NULL)
togayan 0:dfd5cfea7112 214 {
togayan 0:dfd5cfea7112 215 return -1;
togayan 0:dfd5cfea7112 216 }
togayan 0:dfd5cfea7112 217
togayan 0:dfd5cfea7112 218 int src;
togayan 0:dfd5cfea7112 219 int previous = '\0';
togayan 0:dfd5cfea7112 220 while( (src = fgetc(fpSrc)) != EOF )
togayan 0:dfd5cfea7112 221 {
togayan 0:dfd5cfea7112 222 if(previous == '>' && src == '<')
togayan 0:dfd5cfea7112 223 {
togayan 0:dfd5cfea7112 224 fputc('\n', fpDst);
togayan 0:dfd5cfea7112 225 }
togayan 0:dfd5cfea7112 226 fputc(src, fpDst);
togayan 0:dfd5cfea7112 227 previous = src;
togayan 0:dfd5cfea7112 228 }
togayan 0:dfd5cfea7112 229
togayan 0:dfd5cfea7112 230 fclose(fpDst);
togayan 0:dfd5cfea7112 231 fclose(fpSrc);
togayan 0:dfd5cfea7112 232
togayan 0:dfd5cfea7112 233 return 0;
togayan 0:dfd5cfea7112 234 }
togayan 0:dfd5cfea7112 235
togayan 0:dfd5cfea7112 236 int summarizeRss(const char* dstPath, const char* srcPath)
togayan 0:dfd5cfea7112 237 {
togayan 0:dfd5cfea7112 238 FILE* fpSrc = fopen(srcPath, "r");
togayan 0:dfd5cfea7112 239 if (fpSrc == NULL)
togayan 0:dfd5cfea7112 240 {
togayan 0:dfd5cfea7112 241 return -1;
togayan 0:dfd5cfea7112 242 }
togayan 0:dfd5cfea7112 243
togayan 0:dfd5cfea7112 244 FILE* fpDst = fopen(dstPath, "w");
togayan 0:dfd5cfea7112 245 if (fpDst == NULL)
togayan 0:dfd5cfea7112 246 {
togayan 0:dfd5cfea7112 247 return -1;
togayan 0:dfd5cfea7112 248 }
togayan 0:dfd5cfea7112 249
togayan 0:dfd5cfea7112 250 char* ptn[] =
togayan 0:dfd5cfea7112 251 {
togayan 0:dfd5cfea7112 252 "<?xml",
togayan 0:dfd5cfea7112 253 "<rss",
togayan 0:dfd5cfea7112 254 "<channel",
togayan 0:dfd5cfea7112 255 "<lastBuildDate",
togayan 0:dfd5cfea7112 256 "<item",
togayan 0:dfd5cfea7112 257 "<enclosure",
togayan 0:dfd5cfea7112 258 "</item",
togayan 0:dfd5cfea7112 259 "</channel",
togayan 0:dfd5cfea7112 260 "</rss"
togayan 0:dfd5cfea7112 261 };
togayan 0:dfd5cfea7112 262 int ptnSize = sizeof(ptn) / sizeof(char*);
togayan 0:dfd5cfea7112 263
togayan 0:dfd5cfea7112 264 char buff[1024] = {0};
togayan 0:dfd5cfea7112 265 while( fgets(buff, 1024, fpSrc) != NULL )
togayan 0:dfd5cfea7112 266 {
togayan 0:dfd5cfea7112 267 for(int i = 0; i < ptnSize; ++i)
togayan 0:dfd5cfea7112 268 {
togayan 0:dfd5cfea7112 269 if( strncmp(buff, ptn[i], strlen(ptn[i])) == 0 )
togayan 0:dfd5cfea7112 270 {
togayan 0:dfd5cfea7112 271 fputs(buff, fpDst);
togayan 0:dfd5cfea7112 272 break;
togayan 0:dfd5cfea7112 273 }
togayan 0:dfd5cfea7112 274 }
togayan 0:dfd5cfea7112 275 }
togayan 0:dfd5cfea7112 276
togayan 0:dfd5cfea7112 277 fclose(fpDst);
togayan 0:dfd5cfea7112 278 fclose(fpSrc);
togayan 0:dfd5cfea7112 279
togayan 0:dfd5cfea7112 280 return 0;
togayan 0:dfd5cfea7112 281 }
togayan 2:531722036c0a 282
togayan 2:531722036c0a 283 int removePhotos()
togayan 2:531722036c0a 284 {
togayan 2:531722036c0a 285 if(DirHandle* dir = opendir("/usb/DCIM"))
togayan 2:531722036c0a 286 {
togayan 2:531722036c0a 287 int ret = 0;
togayan 2:531722036c0a 288 while(struct dirent* ent = dir->readdir())
togayan 2:531722036c0a 289 {
togayan 2:531722036c0a 290 char filename[32] = {0};
togayan 2:531722036c0a 291 sprintf(filename, "/usb/DCIM/%s", ent->d_name);
togayan 2:531722036c0a 292 printf("remove %s\n", filename);
togayan 2:531722036c0a 293 remove(filename);
togayan 2:531722036c0a 294 ++ret;
togayan 2:531722036c0a 295 }
togayan 2:531722036c0a 296 return ret;
togayan 2:531722036c0a 297 }
togayan 2:531722036c0a 298 else
togayan 2:531722036c0a 299 {
togayan 2:531722036c0a 300 return -1;
togayan 2:531722036c0a 301 }
togayan 2:531722036c0a 302 }
togayan 2:531722036c0a 303
togayan 2:531722036c0a 304 const char* getExtensionFromUrl(const char* url)
togayan 2:531722036c0a 305 {
togayan 2:531722036c0a 306 const char* tail = url;
togayan 2:531722036c0a 307 while('\0' != *tail)
togayan 2:531722036c0a 308 {
togayan 2:531722036c0a 309 ++tail;
togayan 2:531722036c0a 310 }
togayan 2:531722036c0a 311
togayan 2:531722036c0a 312 for(const char* p = tail; p >= url; --p)
togayan 2:531722036c0a 313 {
togayan 2:531722036c0a 314 if ('/' == *p)
togayan 2:531722036c0a 315 {
togayan 2:531722036c0a 316 return tail;
togayan 2:531722036c0a 317 }
togayan 2:531722036c0a 318 if ( '.' == *p )
togayan 2:531722036c0a 319 {
togayan 2:531722036c0a 320 return p+1;
togayan 2:531722036c0a 321 }
togayan 2:531722036c0a 322 }
togayan 2:531722036c0a 323 return tail;
togayan 2:531722036c0a 324 }