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 13:07:06 2012 +0000
Revision:
2:531722036c0a
Parent:
0:dfd5cfea7112
Child:
3:ffbb2b22099a
Only when the album is updated, 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 0:dfd5cfea7112 29 const char* albumRssPath = "/usb/album.xml";
togayan 0:dfd5cfea7112 30 const char* tempPath = "/usb/temp.xml";
togayan 0:dfd5cfea7112 31 const char* summaryPath = "/usb/summary.xml";
togayan 0:dfd5cfea7112 32
togayan 0:dfd5cfea7112 33 int main()
togayan 0:dfd5cfea7112 34 {
togayan 0:dfd5cfea7112 35 printf("\n\n================================\n");
togayan 0:dfd5cfea7112 36 printf("mpod Picasa Photo frame\n");
togayan 0:dfd5cfea7112 37 printf("================================\n\n");
togayan 0:dfd5cfea7112 38
togayan 0:dfd5cfea7112 39 // FSUSB30 switches to HSD1 (mbed)
togayan 0:dfd5cfea7112 40 printf("USB host was switched to HSD1(mbed).\n\n");
togayan 0:dfd5cfea7112 41 fsusb30s = 0; // HSD1
togayan 0:dfd5cfea7112 42
togayan 0:dfd5cfea7112 43 // Network setup
togayan 0:dfd5cfea7112 44 printf("Setup EtherNet with DHCP.\n");
togayan 0:dfd5cfea7112 45 eth.init(); //Use DHCP
togayan 0:dfd5cfea7112 46 eth.connect();
togayan 0:dfd5cfea7112 47
togayan 0:dfd5cfea7112 48 // Obtain original lastBuildDate
togayan 0:dfd5cfea7112 49 char lastBuildDateOriginal[32] = {0};
togayan 0:dfd5cfea7112 50 {
togayan 0:dfd5cfea7112 51 XMLDocument docOriginal;
togayan 0:dfd5cfea7112 52 if(XML_SUCCESS != docOriginal.LoadFile(summaryPath))
togayan 0:dfd5cfea7112 53 {
togayan 0:dfd5cfea7112 54 strcpy(lastBuildDateOriginal, "No original summary.xml in USB memory");
togayan 0:dfd5cfea7112 55 }
togayan 0:dfd5cfea7112 56 else
togayan 0:dfd5cfea7112 57 {
togayan 0:dfd5cfea7112 58 XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
togayan 0:dfd5cfea7112 59 if(NULL == lastBuildDateOriginalElement)
togayan 0:dfd5cfea7112 60 {
togayan 0:dfd5cfea7112 61 strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" element in original RSS");
togayan 0:dfd5cfea7112 62 }
togayan 0:dfd5cfea7112 63 else
togayan 0:dfd5cfea7112 64 {
togayan 0:dfd5cfea7112 65 strcpy(lastBuildDateOriginal, lastBuildDateOriginalElement->GetText());
togayan 0:dfd5cfea7112 66 }
togayan 0:dfd5cfea7112 67 }
togayan 0:dfd5cfea7112 68 }
togayan 0:dfd5cfea7112 69 printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal);
togayan 0:dfd5cfea7112 70
togayan 0:dfd5cfea7112 71 // Download Album
togayan 0:dfd5cfea7112 72 GetFile(albumRssPath, albumRssUrl);
togayan 0:dfd5cfea7112 73
togayan 0:dfd5cfea7112 74 // Summarize RSS
togayan 0:dfd5cfea7112 75 addNewLine(tempPath, albumRssPath);
togayan 0:dfd5cfea7112 76 summarizeRss(summaryPath, tempPath);
togayan 0:dfd5cfea7112 77
togayan 0:dfd5cfea7112 78 // Obtain current lastBuildDate
togayan 0:dfd5cfea7112 79 char lastBuildDateCurrent[32] = {0};
togayan 0:dfd5cfea7112 80
togayan 0:dfd5cfea7112 81 XMLDocument docCurrent;
togayan 0:dfd5cfea7112 82 if(XML_SUCCESS != docCurrent.LoadFile(summaryPath))
togayan 0:dfd5cfea7112 83 {
togayan 0:dfd5cfea7112 84 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 85 error("No current summary.xml in USB memory.\n");
togayan 0:dfd5cfea7112 86 }
togayan 0:dfd5cfea7112 87
togayan 0:dfd5cfea7112 88 XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
togayan 0:dfd5cfea7112 89 if(NULL == lastBuildDateCurrentElement)
togayan 0:dfd5cfea7112 90 {
togayan 0:dfd5cfea7112 91 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 92 error("No \"lastBuildDate\" element in current RSS.\n");
togayan 0:dfd5cfea7112 93 }
togayan 0:dfd5cfea7112 94 strcpy(lastBuildDateCurrent, lastBuildDateCurrentElement->GetText());
togayan 0:dfd5cfea7112 95 printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent);
togayan 0:dfd5cfea7112 96
togayan 2:531722036c0a 97 if( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) != 0 )
togayan 0:dfd5cfea7112 98 {
togayan 2:531722036c0a 99 printf("lastBuildDate (original) != lastBuildDate (current)\n");
togayan 2:531722036c0a 100 if(removePhotos() < 0)
togayan 2:531722036c0a 101 {
togayan 2:531722036c0a 102 fsusb30s = 1; // HSD2
togayan 2:531722036c0a 103 error("No \"DCIM\" folder in MSD.\n");
togayan 2:531722036c0a 104 }
togayan 2:531722036c0a 105
togayan 2:531722036c0a 106 char photoUrl[256] = {0};
togayan 2:531722036c0a 107 char photoPath[32] = {0};
togayan 2:531722036c0a 108 int photoNo = 1;
togayan 2:531722036c0a 109 XMLElement* itemElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item");
togayan 2:531722036c0a 110 if(NULL == itemElement)
togayan 2:531722036c0a 111 {
togayan 2:531722036c0a 112 fsusb30s = 1; // HSD2
togayan 2:531722036c0a 113 error("No \"enclosure\" element in current RSS.\n");
togayan 2:531722036c0a 114 }
togayan 0:dfd5cfea7112 115 strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
togayan 2:531722036c0a 116 const char* extension = getExtensionFromUrl(photoUrl);
togayan 2:531722036c0a 117 sprintf(photoPath, "/usb/DCIM/%08d.%s", photoNo, extension);
togayan 0:dfd5cfea7112 118 GetFile(photoPath, photoUrl);
togayan 0:dfd5cfea7112 119 ++photoNo;
togayan 2:531722036c0a 120
togayan 2:531722036c0a 121 while( (itemElement = itemElement->NextSiblingElement( "item" ) ) != NULL )
togayan 2:531722036c0a 122 {
togayan 2:531722036c0a 123 strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url"));
togayan 2:531722036c0a 124 sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo);
togayan 2:531722036c0a 125 GetFile(photoPath, photoUrl);
togayan 2:531722036c0a 126 ++photoNo;
togayan 2:531722036c0a 127 }
togayan 2:531722036c0a 128 }
togayan 2:531722036c0a 129 else
togayan 2:531722036c0a 130 {
togayan 2:531722036c0a 131 printf("lastBuildDate (original) == lastBuildDate (current)\n");
togayan 0:dfd5cfea7112 132 }
togayan 0:dfd5cfea7112 133
togayan 0:dfd5cfea7112 134 // Wait for the completion of writing to USB Mass Storage Device.
togayan 0:dfd5cfea7112 135 wait(1);
togayan 0:dfd5cfea7112 136
togayan 0:dfd5cfea7112 137 // FSUSB30 switches to HSD2 (External Device)
togayan 0:dfd5cfea7112 138 printf("\nUSB host was switched to HSD2(External Device).\n");
togayan 0:dfd5cfea7112 139 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 140
togayan 0:dfd5cfea7112 141 // blink LED
togayan 0:dfd5cfea7112 142 led1.startBlink();
togayan 0:dfd5cfea7112 143 ethGreen.startBlink();
togayan 0:dfd5cfea7112 144
togayan 0:dfd5cfea7112 145 while(true){}
togayan 0:dfd5cfea7112 146 }
togayan 0:dfd5cfea7112 147
togayan 0:dfd5cfea7112 148 int GetFile(const char *path, const char *url)
togayan 0:dfd5cfea7112 149 {
togayan 0:dfd5cfea7112 150 led2.startBlink();
togayan 0:dfd5cfea7112 151 ethYellow.startBlink();
togayan 0:dfd5cfea7112 152 printf("\nGetting %s\n", url);
togayan 0:dfd5cfea7112 153
togayan 0:dfd5cfea7112 154 timer.stop();
togayan 0:dfd5cfea7112 155 timer.reset();
togayan 0:dfd5cfea7112 156 timer.start();
togayan 0:dfd5cfea7112 157
togayan 0:dfd5cfea7112 158 HTTPFile file(path);
togayan 0:dfd5cfea7112 159 HTTPResult retGet = http.get(url, &file);
togayan 0:dfd5cfea7112 160 if (retGet != HTTP_OK)
togayan 0:dfd5cfea7112 161 {
togayan 0:dfd5cfea7112 162 fsusb30s = 1; // HSD2
togayan 0:dfd5cfea7112 163 error("Error in http.get in GetFile(): %d\n", retGet);
togayan 0:dfd5cfea7112 164 }
togayan 0:dfd5cfea7112 165 file.clear();
togayan 0:dfd5cfea7112 166
togayan 0:dfd5cfea7112 167 timer.stop();
togayan 0:dfd5cfea7112 168 printf("timer.read_ms(): %d\n", timer.read_ms());
togayan 0:dfd5cfea7112 169
togayan 0:dfd5cfea7112 170 led2.finishBlink();
togayan 0:dfd5cfea7112 171 ethYellow.finishBlink();
togayan 0:dfd5cfea7112 172 return (0);
togayan 0:dfd5cfea7112 173 }
togayan 0:dfd5cfea7112 174
togayan 0:dfd5cfea7112 175 int addNewLine(const char* dstPath, const char* srcPath)
togayan 0:dfd5cfea7112 176 {
togayan 0:dfd5cfea7112 177 FILE* fpSrc = fopen(srcPath, "r");
togayan 0:dfd5cfea7112 178 if (fpSrc == NULL)
togayan 0:dfd5cfea7112 179 {
togayan 0:dfd5cfea7112 180 return -1;
togayan 0:dfd5cfea7112 181 }
togayan 0:dfd5cfea7112 182
togayan 0:dfd5cfea7112 183 FILE* fpDst = fopen(dstPath, "w");
togayan 0:dfd5cfea7112 184 if (fpDst == NULL)
togayan 0:dfd5cfea7112 185 {
togayan 0:dfd5cfea7112 186 return -1;
togayan 0:dfd5cfea7112 187 }
togayan 0:dfd5cfea7112 188
togayan 0:dfd5cfea7112 189 int src;
togayan 0:dfd5cfea7112 190 int previous = '\0';
togayan 0:dfd5cfea7112 191 while( (src = fgetc(fpSrc)) != EOF )
togayan 0:dfd5cfea7112 192 {
togayan 0:dfd5cfea7112 193 if(previous == '>' && src == '<')
togayan 0:dfd5cfea7112 194 {
togayan 0:dfd5cfea7112 195 fputc('\n', fpDst);
togayan 0:dfd5cfea7112 196 }
togayan 0:dfd5cfea7112 197 fputc(src, fpDst);
togayan 0:dfd5cfea7112 198 previous = src;
togayan 0:dfd5cfea7112 199 }
togayan 0:dfd5cfea7112 200
togayan 0:dfd5cfea7112 201 fclose(fpDst);
togayan 0:dfd5cfea7112 202 fclose(fpSrc);
togayan 0:dfd5cfea7112 203
togayan 0:dfd5cfea7112 204 return 0;
togayan 0:dfd5cfea7112 205 }
togayan 0:dfd5cfea7112 206
togayan 0:dfd5cfea7112 207 int summarizeRss(const char* dstPath, const char* srcPath)
togayan 0:dfd5cfea7112 208 {
togayan 0:dfd5cfea7112 209 FILE* fpSrc = fopen(srcPath, "r");
togayan 0:dfd5cfea7112 210 if (fpSrc == NULL)
togayan 0:dfd5cfea7112 211 {
togayan 0:dfd5cfea7112 212 return -1;
togayan 0:dfd5cfea7112 213 }
togayan 0:dfd5cfea7112 214
togayan 0:dfd5cfea7112 215 FILE* fpDst = fopen(dstPath, "w");
togayan 0:dfd5cfea7112 216 if (fpDst == NULL)
togayan 0:dfd5cfea7112 217 {
togayan 0:dfd5cfea7112 218 return -1;
togayan 0:dfd5cfea7112 219 }
togayan 0:dfd5cfea7112 220
togayan 0:dfd5cfea7112 221 char* ptn[] =
togayan 0:dfd5cfea7112 222 {
togayan 0:dfd5cfea7112 223 "<?xml",
togayan 0:dfd5cfea7112 224 "<rss",
togayan 0:dfd5cfea7112 225 "<channel",
togayan 0:dfd5cfea7112 226 "<lastBuildDate",
togayan 0:dfd5cfea7112 227 "<item",
togayan 0:dfd5cfea7112 228 "<enclosure",
togayan 0:dfd5cfea7112 229 "</item",
togayan 0:dfd5cfea7112 230 "</channel",
togayan 0:dfd5cfea7112 231 "</rss"
togayan 0:dfd5cfea7112 232 };
togayan 0:dfd5cfea7112 233 int ptnSize = sizeof(ptn) / sizeof(char*);
togayan 0:dfd5cfea7112 234
togayan 0:dfd5cfea7112 235 char buff[1024] = {0};
togayan 0:dfd5cfea7112 236 while( fgets(buff, 1024, fpSrc) != NULL )
togayan 0:dfd5cfea7112 237 {
togayan 0:dfd5cfea7112 238 for(int i = 0; i < ptnSize; ++i)
togayan 0:dfd5cfea7112 239 {
togayan 0:dfd5cfea7112 240 if( strncmp(buff, ptn[i], strlen(ptn[i])) == 0 )
togayan 0:dfd5cfea7112 241 {
togayan 0:dfd5cfea7112 242 fputs(buff, fpDst);
togayan 0:dfd5cfea7112 243 break;
togayan 0:dfd5cfea7112 244 }
togayan 0:dfd5cfea7112 245 }
togayan 0:dfd5cfea7112 246 }
togayan 0:dfd5cfea7112 247
togayan 0:dfd5cfea7112 248 fclose(fpDst);
togayan 0:dfd5cfea7112 249 fclose(fpSrc);
togayan 0:dfd5cfea7112 250
togayan 0:dfd5cfea7112 251 return 0;
togayan 0:dfd5cfea7112 252 }
togayan 2:531722036c0a 253
togayan 2:531722036c0a 254 int removePhotos()
togayan 2:531722036c0a 255 {
togayan 2:531722036c0a 256 if(DirHandle* dir = opendir("/usb/DCIM"))
togayan 2:531722036c0a 257 {
togayan 2:531722036c0a 258 int ret = 0;
togayan 2:531722036c0a 259 while(struct dirent* ent = dir->readdir())
togayan 2:531722036c0a 260 {
togayan 2:531722036c0a 261 char filename[32] = {0};
togayan 2:531722036c0a 262 sprintf(filename, "/usb/DCIM/%s", ent->d_name);
togayan 2:531722036c0a 263 printf("remove %s\n", filename);
togayan 2:531722036c0a 264 remove(filename);
togayan 2:531722036c0a 265 ++ret;
togayan 2:531722036c0a 266 }
togayan 2:531722036c0a 267 return ret;
togayan 2:531722036c0a 268 }
togayan 2:531722036c0a 269 else
togayan 2:531722036c0a 270 {
togayan 2:531722036c0a 271 return -1;
togayan 2:531722036c0a 272 }
togayan 2:531722036c0a 273 }
togayan 2:531722036c0a 274
togayan 2:531722036c0a 275 const char* getExtensionFromUrl(const char* url)
togayan 2:531722036c0a 276 {
togayan 2:531722036c0a 277 const char* tail = url;
togayan 2:531722036c0a 278 while('\0' != *tail)
togayan 2:531722036c0a 279 {
togayan 2:531722036c0a 280 ++tail;
togayan 2:531722036c0a 281 }
togayan 2:531722036c0a 282
togayan 2:531722036c0a 283 for(const char* p = tail; p >= url; --p)
togayan 2:531722036c0a 284 {
togayan 2:531722036c0a 285 if ('/' == *p)
togayan 2:531722036c0a 286 {
togayan 2:531722036c0a 287 return tail;
togayan 2:531722036c0a 288 }
togayan 2:531722036c0a 289 if ( '.' == *p )
togayan 2:531722036c0a 290 {
togayan 2:531722036c0a 291 return p+1;
togayan 2:531722036c0a 292 }
togayan 2:531722036c0a 293 }
togayan 2:531722036c0a 294 return tail;
togayan 2:531722036c0a 295 }