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を指定してからご利用下さい。
main.cpp@5:66c3398a14c9, 2012-08-28 (annotated)
- Committer:
- togayan
- Date:
- Tue Aug 28 14:41:17 2012 +0000
- Revision:
- 5:66c3398a14c9
- Parent:
- 4:f2d619e67d44
- Child:
- 6:83383116c88a
Large RSS can be read.
Who changed what in which revision?
User | Revision | Line number | New 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 | 5:66c3398a14c9 | 7 | #include <cstring> |
togayan | 0:dfd5cfea7112 | 8 | |
togayan | 0:dfd5cfea7112 | 9 | int GetFile(const char *path, const char *url); |
togayan | 0:dfd5cfea7112 | 10 | int summarizeRss(const char* dstPath, const char* srcPath); |
togayan | 5:66c3398a14c9 | 11 | int removeContents(const char* url); |
togayan | 2:531722036c0a | 12 | const char* getExtensionFromUrl(const char* url); |
togayan | 0:dfd5cfea7112 | 13 | |
togayan | 0:dfd5cfea7112 | 14 | EthernetInterface eth; |
togayan | 0:dfd5cfea7112 | 15 | HTTPClient http; |
togayan | 0:dfd5cfea7112 | 16 | MSCFileSystem usb("usb"); |
togayan | 0:dfd5cfea7112 | 17 | BlinkLed led1(LED1, 0.02); |
togayan | 0:dfd5cfea7112 | 18 | BlinkLed led2(LED2, 0.2); |
togayan | 0:dfd5cfea7112 | 19 | BlinkLed ethGreen(p26, 0.02); |
togayan | 0:dfd5cfea7112 | 20 | BlinkLed ethYellow(p25, 0.2); |
togayan | 0:dfd5cfea7112 | 21 | DigitalOut fsusb30s(p9); |
togayan | 0:dfd5cfea7112 | 22 | |
togayan | 0:dfd5cfea7112 | 23 | /***** Please specify "albumRssUrl" *****/ |
togayan | 0:dfd5cfea7112 | 24 | const char* albumRssUrl = "http://picasaweb.google.com/data/feed/base/user/*****/albumid/*****?alt=rss&kind=photo&authkey=*****&hl=ja"; |
togayan | 3:ffbb2b22099a | 25 | |
togayan | 0:dfd5cfea7112 | 26 | const char* albumRssPath = "/usb/album.xml"; |
togayan | 5:66c3398a14c9 | 27 | const char* summaryPath = "/usb/summary.txt"; |
togayan | 5:66c3398a14c9 | 28 | const char* contentsFolder = "/usb/DCIM"; |
togayan | 0:dfd5cfea7112 | 29 | |
togayan | 0:dfd5cfea7112 | 30 | int main() |
togayan | 0:dfd5cfea7112 | 31 | { |
togayan | 5:66c3398a14c9 | 32 | puts(""); |
togayan | 5:66c3398a14c9 | 33 | puts("================================"); |
togayan | 5:66c3398a14c9 | 34 | puts("mpod Picasa Photo frame"); |
togayan | 5:66c3398a14c9 | 35 | puts("================================\n"); |
togayan | 0:dfd5cfea7112 | 36 | |
togayan | 3:ffbb2b22099a | 37 | // Check albumRssUrl |
togayan | 3:ffbb2b22099a | 38 | if(NULL != strstr(albumRssUrl, "*****")) |
togayan | 3:ffbb2b22099a | 39 | { |
togayan | 3:ffbb2b22099a | 40 | error("[ERROR] Please specify the RSS of YOUR album to \"albumRssUrl\" in the firmware.\n"); |
togayan | 3:ffbb2b22099a | 41 | } |
togayan | 3:ffbb2b22099a | 42 | if(NULL != strstr(albumRssUrl, "https")) |
togayan | 3:ffbb2b22099a | 43 | { |
togayan | 3:ffbb2b22099a | 44 | error("[ERROR] Please specify the URL of the RSS in \"HTTP\" format.\n"); |
togayan | 3:ffbb2b22099a | 45 | } |
togayan | 3:ffbb2b22099a | 46 | |
togayan | 5:66c3398a14c9 | 47 | // Indicate downloading |
togayan | 5:66c3398a14c9 | 48 | led2.startBlink(); |
togayan | 5:66c3398a14c9 | 49 | ethYellow.startBlink(); |
togayan | 5:66c3398a14c9 | 50 | |
togayan | 0:dfd5cfea7112 | 51 | // FSUSB30 switches to HSD1 (mbed) |
togayan | 5:66c3398a14c9 | 52 | puts("USB host was switched to HSD1(mbed).\n"); |
togayan | 0:dfd5cfea7112 | 53 | fsusb30s = 0; // HSD1 |
togayan | 0:dfd5cfea7112 | 54 | |
togayan | 0:dfd5cfea7112 | 55 | // Network setup |
togayan | 5:66c3398a14c9 | 56 | puts("Setup EtherNet with DHCP."); |
togayan | 0:dfd5cfea7112 | 57 | eth.init(); //Use DHCP |
togayan | 0:dfd5cfea7112 | 58 | eth.connect(); |
togayan | 5:66c3398a14c9 | 59 | printf("IP Address is %s\n\n", eth.getIPAddress()); |
togayan | 0:dfd5cfea7112 | 60 | |
togayan | 0:dfd5cfea7112 | 61 | // Obtain original lastBuildDate |
togayan | 5:66c3398a14c9 | 62 | char lastBuildDateOriginal[40] = {0}; |
togayan | 5:66c3398a14c9 | 63 | FILE* fpOriginal = fopen(summaryPath, "r"); |
togayan | 5:66c3398a14c9 | 64 | if (fpOriginal == NULL) |
togayan | 0:dfd5cfea7112 | 65 | { |
togayan | 5:66c3398a14c9 | 66 | strcpy(lastBuildDateOriginal, "No summary.txt in USB memory"); |
togayan | 5:66c3398a14c9 | 67 | } |
togayan | 5:66c3398a14c9 | 68 | else |
togayan | 5:66c3398a14c9 | 69 | { |
togayan | 5:66c3398a14c9 | 70 | if(fgets(lastBuildDateOriginal, 40, fpOriginal) == NULL) |
togayan | 0:dfd5cfea7112 | 71 | { |
togayan | 5:66c3398a14c9 | 72 | strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" in RSS"); |
togayan | 0:dfd5cfea7112 | 73 | } |
togayan | 0:dfd5cfea7112 | 74 | else |
togayan | 0:dfd5cfea7112 | 75 | { |
togayan | 5:66c3398a14c9 | 76 | lastBuildDateOriginal[strlen(lastBuildDateOriginal) - 1] = '\0'; |
togayan | 0:dfd5cfea7112 | 77 | } |
togayan | 5:66c3398a14c9 | 78 | fclose(fpOriginal); |
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 | 5:66c3398a14c9 | 86 | summarizeRss(summaryPath, albumRssPath); |
togayan | 0:dfd5cfea7112 | 87 | |
togayan | 5:66c3398a14c9 | 88 | // Obtain current lastBuildDate |
togayan | 5:66c3398a14c9 | 89 | char lastBuildDateCurrent[40] = {0}; |
togayan | 5:66c3398a14c9 | 90 | FILE* fpCurrent = fopen(summaryPath, "r"); |
togayan | 5:66c3398a14c9 | 91 | if (fpCurrent == NULL) |
togayan | 0:dfd5cfea7112 | 92 | { |
togayan | 0:dfd5cfea7112 | 93 | fsusb30s = 1; // HSD2 |
togayan | 5:66c3398a14c9 | 94 | error("No current summary.txt in USB memory.\n"); |
togayan | 0:dfd5cfea7112 | 95 | } |
togayan | 5:66c3398a14c9 | 96 | else |
togayan | 0:dfd5cfea7112 | 97 | { |
togayan | 5:66c3398a14c9 | 98 | if(fgets(lastBuildDateCurrent, 40, fpCurrent) == NULL) |
togayan | 5:66c3398a14c9 | 99 | { |
togayan | 5:66c3398a14c9 | 100 | fsusb30s = 1; // HSD2 |
togayan | 5:66c3398a14c9 | 101 | error("No \"lastBuildDate\" element in current RSS.\n"); |
togayan | 5:66c3398a14c9 | 102 | } |
togayan | 5:66c3398a14c9 | 103 | else |
togayan | 5:66c3398a14c9 | 104 | { |
togayan | 5:66c3398a14c9 | 105 | lastBuildDateCurrent[strlen(lastBuildDateCurrent) - 1] = '\0'; |
togayan | 5:66c3398a14c9 | 106 | } |
togayan | 0:dfd5cfea7112 | 107 | } |
togayan | 0:dfd5cfea7112 | 108 | printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent); |
togayan | 0:dfd5cfea7112 | 109 | |
togayan | 3:ffbb2b22099a | 110 | // Determine the necessity of downloading new Photos. |
togayan | 3:ffbb2b22099a | 111 | bool flgDownloadPhoto = false; |
togayan | 3:ffbb2b22099a | 112 | if ( strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0 ) |
togayan | 3:ffbb2b22099a | 113 | { |
togayan | 5:66c3398a14c9 | 114 | puts("lastBuildDate (original) == lastBuildDate (current)"); |
togayan | 5:66c3398a14c9 | 115 | if(NULL == opendir(contentsFolder)) // check an existance of DCIM folder |
togayan | 3:ffbb2b22099a | 116 | { |
togayan | 3:ffbb2b22099a | 117 | printf("However, no DCIM folder in USB memory\n"); |
togayan | 3:ffbb2b22099a | 118 | flgDownloadPhoto = true; |
togayan | 3:ffbb2b22099a | 119 | } |
togayan | 3:ffbb2b22099a | 120 | else |
togayan | 3:ffbb2b22099a | 121 | { |
togayan | 3:ffbb2b22099a | 122 | //Should be checked whether files exist. |
togayan | 3:ffbb2b22099a | 123 | flgDownloadPhoto = false; |
togayan | 3:ffbb2b22099a | 124 | } |
togayan | 3:ffbb2b22099a | 125 | } |
togayan | 3:ffbb2b22099a | 126 | else |
togayan | 0:dfd5cfea7112 | 127 | { |
togayan | 5:66c3398a14c9 | 128 | puts("lastBuildDate (original) != lastBuildDate (current)"); |
togayan | 3:ffbb2b22099a | 129 | flgDownloadPhoto = true; |
togayan | 3:ffbb2b22099a | 130 | } |
togayan | 3:ffbb2b22099a | 131 | |
togayan | 3:ffbb2b22099a | 132 | // Download new Photos |
togayan | 3:ffbb2b22099a | 133 | if(flgDownloadPhoto) |
togayan | 3:ffbb2b22099a | 134 | { |
togayan | 5:66c3398a14c9 | 135 | if(removeContents(contentsFolder) < 0) |
togayan | 2:531722036c0a | 136 | { |
togayan | 5:66c3398a14c9 | 137 | mkdir(contentsFolder, 0777); |
togayan | 2:531722036c0a | 138 | } |
togayan | 2:531722036c0a | 139 | |
togayan | 5:66c3398a14c9 | 140 | char photoUrl[128] = {0}; |
togayan | 5:66c3398a14c9 | 141 | char photoPath[24] = {0}; |
togayan | 2:531722036c0a | 142 | int photoNo = 1; |
togayan | 5:66c3398a14c9 | 143 | while(fgets(photoUrl, 128, fpCurrent) != NULL) |
togayan | 2:531722036c0a | 144 | { |
togayan | 5:66c3398a14c9 | 145 | photoUrl[strlen(photoUrl) - 1] = '\0'; |
togayan | 5:66c3398a14c9 | 146 | sprintf(photoPath, "%s/%08d.%s", contentsFolder, photoNo, getExtensionFromUrl(photoUrl)); |
togayan | 2:531722036c0a | 147 | GetFile(photoPath, photoUrl); |
togayan | 2:531722036c0a | 148 | ++photoNo; |
togayan | 2:531722036c0a | 149 | } |
togayan | 2:531722036c0a | 150 | } |
togayan | 5:66c3398a14c9 | 151 | fclose(fpCurrent); |
togayan | 0:dfd5cfea7112 | 152 | |
togayan | 0:dfd5cfea7112 | 153 | // Wait for the completion of writing to USB Mass Storage Device. |
togayan | 0:dfd5cfea7112 | 154 | wait(1); |
togayan | 0:dfd5cfea7112 | 155 | |
togayan | 0:dfd5cfea7112 | 156 | // FSUSB30 switches to HSD2 (External Device) |
togayan | 5:66c3398a14c9 | 157 | puts("\nUSB host was switched to HSD2(External Device).\n"); |
togayan | 0:dfd5cfea7112 | 158 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 159 | |
togayan | 5:66c3398a14c9 | 160 | // Indicate finish downloading |
togayan | 5:66c3398a14c9 | 161 | led2.finishBlink(); |
togayan | 5:66c3398a14c9 | 162 | ethYellow.finishBlink(); |
togayan | 0:dfd5cfea7112 | 163 | led1.startBlink(); |
togayan | 0:dfd5cfea7112 | 164 | ethGreen.startBlink(); |
togayan | 0:dfd5cfea7112 | 165 | |
togayan | 0:dfd5cfea7112 | 166 | while(true){} |
togayan | 0:dfd5cfea7112 | 167 | } |
togayan | 0:dfd5cfea7112 | 168 | |
togayan | 0:dfd5cfea7112 | 169 | int GetFile(const char *path, const char *url) |
togayan | 0:dfd5cfea7112 | 170 | { |
togayan | 5:66c3398a14c9 | 171 | printf("Getting %s -> %s\n", url, path); |
togayan | 0:dfd5cfea7112 | 172 | |
togayan | 0:dfd5cfea7112 | 173 | HTTPFile file(path); |
togayan | 0:dfd5cfea7112 | 174 | HTTPResult retGet = http.get(url, &file); |
togayan | 0:dfd5cfea7112 | 175 | if (retGet != HTTP_OK) |
togayan | 0:dfd5cfea7112 | 176 | { |
togayan | 0:dfd5cfea7112 | 177 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 178 | error("Error in http.get in GetFile(): %d\n", retGet); |
togayan | 0:dfd5cfea7112 | 179 | } |
togayan | 0:dfd5cfea7112 | 180 | file.clear(); |
togayan | 0:dfd5cfea7112 | 181 | |
togayan | 0:dfd5cfea7112 | 182 | return (0); |
togayan | 0:dfd5cfea7112 | 183 | } |
togayan | 0:dfd5cfea7112 | 184 | |
togayan | 5:66c3398a14c9 | 185 | int summarizeRss(const char* dstPath, const char* srcPath) |
togayan | 0:dfd5cfea7112 | 186 | { |
togayan | 5:66c3398a14c9 | 187 | puts("Summarizing RSS."); |
togayan | 5:66c3398a14c9 | 188 | |
togayan | 0:dfd5cfea7112 | 189 | FILE* fpSrc = fopen(srcPath, "r"); |
togayan | 0:dfd5cfea7112 | 190 | if (fpSrc == NULL) |
togayan | 0:dfd5cfea7112 | 191 | { |
togayan | 0:dfd5cfea7112 | 192 | return -1; |
togayan | 0:dfd5cfea7112 | 193 | } |
togayan | 0:dfd5cfea7112 | 194 | |
togayan | 0:dfd5cfea7112 | 195 | FILE* fpDst = fopen(dstPath, "w"); |
togayan | 0:dfd5cfea7112 | 196 | if (fpDst == NULL) |
togayan | 0:dfd5cfea7112 | 197 | { |
togayan | 5:66c3398a14c9 | 198 | fclose(fpSrc); |
togayan | 0:dfd5cfea7112 | 199 | return -1; |
togayan | 0:dfd5cfea7112 | 200 | } |
togayan | 0:dfd5cfea7112 | 201 | |
togayan | 5:66c3398a14c9 | 202 | char buff[1024] = {0}; |
togayan | 5:66c3398a14c9 | 203 | char* buffPos = buff; |
togayan | 5:66c3398a14c9 | 204 | |
togayan | 5:66c3398a14c9 | 205 | int present; |
togayan | 0:dfd5cfea7112 | 206 | int previous = '\0'; |
togayan | 5:66c3398a14c9 | 207 | while( (present = fgetc(fpSrc)) != EOF ) |
togayan | 0:dfd5cfea7112 | 208 | { |
togayan | 5:66c3398a14c9 | 209 | if(previous == '>' && present == '<') |
togayan | 0:dfd5cfea7112 | 210 | { |
togayan | 5:66c3398a14c9 | 211 | if( strncmp(buff, "<lastBuildDate", 14) == 0 ) |
togayan | 5:66c3398a14c9 | 212 | { |
togayan | 5:66c3398a14c9 | 213 | *strchr(buff + 15, '<') = '\0'; |
togayan | 5:66c3398a14c9 | 214 | fprintf(fpDst, "%s\n", buff + 15); |
togayan | 5:66c3398a14c9 | 215 | } |
togayan | 5:66c3398a14c9 | 216 | else if( strncmp(buff, "<enclosure", 10) == 0 ) |
togayan | 5:66c3398a14c9 | 217 | { |
togayan | 5:66c3398a14c9 | 218 | *strchr(buff + 34, '\'') = '\0'; |
togayan | 5:66c3398a14c9 | 219 | fprintf(fpDst, "%s\n", buff + 34); |
togayan | 5:66c3398a14c9 | 220 | } |
togayan | 5:66c3398a14c9 | 221 | buffPos = buff; |
togayan | 0:dfd5cfea7112 | 222 | } |
togayan | 5:66c3398a14c9 | 223 | *buffPos++ = present; |
togayan | 5:66c3398a14c9 | 224 | previous = present; |
togayan | 0:dfd5cfea7112 | 225 | } |
togayan | 0:dfd5cfea7112 | 226 | |
togayan | 0:dfd5cfea7112 | 227 | fclose(fpDst); |
togayan | 0:dfd5cfea7112 | 228 | fclose(fpSrc); |
togayan | 0:dfd5cfea7112 | 229 | |
togayan | 0:dfd5cfea7112 | 230 | return 0; |
togayan | 0:dfd5cfea7112 | 231 | } |
togayan | 0:dfd5cfea7112 | 232 | |
togayan | 5:66c3398a14c9 | 233 | int removeContents(const char* dirName) |
togayan | 0:dfd5cfea7112 | 234 | { |
togayan | 5:66c3398a14c9 | 235 | if(DirHandle* dir = opendir(dirName)) |
togayan | 2:531722036c0a | 236 | { |
togayan | 2:531722036c0a | 237 | int ret = 0; |
togayan | 2:531722036c0a | 238 | while(struct dirent* ent = dir->readdir()) |
togayan | 2:531722036c0a | 239 | { |
togayan | 2:531722036c0a | 240 | char filename[32] = {0}; |
togayan | 5:66c3398a14c9 | 241 | sprintf(filename, "%s/%s", dirName, ent->d_name); |
togayan | 2:531722036c0a | 242 | printf("remove %s\n", filename); |
togayan | 2:531722036c0a | 243 | remove(filename); |
togayan | 2:531722036c0a | 244 | ++ret; |
togayan | 2:531722036c0a | 245 | } |
togayan | 2:531722036c0a | 246 | return ret; |
togayan | 2:531722036c0a | 247 | } |
togayan | 2:531722036c0a | 248 | else |
togayan | 2:531722036c0a | 249 | { |
togayan | 2:531722036c0a | 250 | return -1; |
togayan | 2:531722036c0a | 251 | } |
togayan | 2:531722036c0a | 252 | } |
togayan | 2:531722036c0a | 253 | |
togayan | 2:531722036c0a | 254 | const char* getExtensionFromUrl(const char* url) |
togayan | 2:531722036c0a | 255 | { |
togayan | 2:531722036c0a | 256 | const char* tail = url; |
togayan | 2:531722036c0a | 257 | while('\0' != *tail) |
togayan | 2:531722036c0a | 258 | { |
togayan | 2:531722036c0a | 259 | ++tail; |
togayan | 2:531722036c0a | 260 | } |
togayan | 2:531722036c0a | 261 | |
togayan | 2:531722036c0a | 262 | for(const char* p = tail; p >= url; --p) |
togayan | 2:531722036c0a | 263 | { |
togayan | 2:531722036c0a | 264 | if ('/' == *p) |
togayan | 2:531722036c0a | 265 | { |
togayan | 2:531722036c0a | 266 | return tail; |
togayan | 2:531722036c0a | 267 | } |
togayan | 2:531722036c0a | 268 | if ( '.' == *p ) |
togayan | 2:531722036c0a | 269 | { |
togayan | 2:531722036c0a | 270 | return p+1; |
togayan | 2:531722036c0a | 271 | } |
togayan | 2:531722036c0a | 272 | } |
togayan | 2:531722036c0a | 273 | return tail; |
togayan | 2:531722036c0a | 274 | } |