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@0:dfd5cfea7112, 2012-08-22 (annotated)
- Committer:
- togayan
- Date:
- Wed Aug 22 16:00:38 2012 +0000
- Revision:
- 0:dfd5cfea7112
- Child:
- 2:531722036c0a
1st version of mpod_picasa_photoframe
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 | 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 | 0:dfd5cfea7112 | 14 | |
togayan | 0:dfd5cfea7112 | 15 | EthernetInterface eth; |
togayan | 0:dfd5cfea7112 | 16 | HTTPClient http; |
togayan | 0:dfd5cfea7112 | 17 | MSCFileSystem usb("usb"); |
togayan | 0:dfd5cfea7112 | 18 | BlinkLed led1(LED1, 0.02); |
togayan | 0:dfd5cfea7112 | 19 | BlinkLed led2(LED2, 0.2); |
togayan | 0:dfd5cfea7112 | 20 | BlinkLed ethGreen(p26, 0.02); |
togayan | 0:dfd5cfea7112 | 21 | BlinkLed ethYellow(p25, 0.2); |
togayan | 0:dfd5cfea7112 | 22 | DigitalOut fsusb30s(p9); |
togayan | 0:dfd5cfea7112 | 23 | Timer timer; |
togayan | 0:dfd5cfea7112 | 24 | |
togayan | 0:dfd5cfea7112 | 25 | /***** Please specify "albumRssUrl" *****/ |
togayan | 0:dfd5cfea7112 | 26 | const char* albumRssUrl = "http://picasaweb.google.com/data/feed/base/user/*****/albumid/*****?alt=rss&kind=photo&authkey=*****&hl=ja"; |
togayan | 0:dfd5cfea7112 | 27 | |
togayan | 0:dfd5cfea7112 | 28 | const char* albumRssPath = "/usb/album.xml"; |
togayan | 0:dfd5cfea7112 | 29 | const char* tempPath = "/usb/temp.xml"; |
togayan | 0:dfd5cfea7112 | 30 | const char* summaryPath = "/usb/summary.xml"; |
togayan | 0:dfd5cfea7112 | 31 | |
togayan | 0:dfd5cfea7112 | 32 | int main() |
togayan | 0:dfd5cfea7112 | 33 | { |
togayan | 0:dfd5cfea7112 | 34 | printf("\n\n================================\n"); |
togayan | 0:dfd5cfea7112 | 35 | printf("mpod Picasa Photo frame\n"); |
togayan | 0:dfd5cfea7112 | 36 | printf("================================\n\n"); |
togayan | 0:dfd5cfea7112 | 37 | |
togayan | 0:dfd5cfea7112 | 38 | // FSUSB30 switches to HSD1 (mbed) |
togayan | 0:dfd5cfea7112 | 39 | printf("USB host was switched to HSD1(mbed).\n\n"); |
togayan | 0:dfd5cfea7112 | 40 | fsusb30s = 0; // HSD1 |
togayan | 0:dfd5cfea7112 | 41 | |
togayan | 0:dfd5cfea7112 | 42 | // Network setup |
togayan | 0:dfd5cfea7112 | 43 | printf("Setup EtherNet with DHCP.\n"); |
togayan | 0:dfd5cfea7112 | 44 | eth.init(); //Use DHCP |
togayan | 0:dfd5cfea7112 | 45 | eth.connect(); |
togayan | 0:dfd5cfea7112 | 46 | |
togayan | 0:dfd5cfea7112 | 47 | // Obtain original lastBuildDate |
togayan | 0:dfd5cfea7112 | 48 | char lastBuildDateOriginal[32] = {0}; |
togayan | 0:dfd5cfea7112 | 49 | { |
togayan | 0:dfd5cfea7112 | 50 | XMLDocument docOriginal; |
togayan | 0:dfd5cfea7112 | 51 | if(XML_SUCCESS != docOriginal.LoadFile(summaryPath)) |
togayan | 0:dfd5cfea7112 | 52 | { |
togayan | 0:dfd5cfea7112 | 53 | strcpy(lastBuildDateOriginal, "No original summary.xml in USB memory"); |
togayan | 0:dfd5cfea7112 | 54 | } |
togayan | 0:dfd5cfea7112 | 55 | else |
togayan | 0:dfd5cfea7112 | 56 | { |
togayan | 0:dfd5cfea7112 | 57 | XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate"); |
togayan | 0:dfd5cfea7112 | 58 | if(NULL == lastBuildDateOriginalElement) |
togayan | 0:dfd5cfea7112 | 59 | { |
togayan | 0:dfd5cfea7112 | 60 | strcpy(lastBuildDateOriginal, "No \"lastBuildDate\" element in original RSS"); |
togayan | 0:dfd5cfea7112 | 61 | } |
togayan | 0:dfd5cfea7112 | 62 | else |
togayan | 0:dfd5cfea7112 | 63 | { |
togayan | 0:dfd5cfea7112 | 64 | strcpy(lastBuildDateOriginal, lastBuildDateOriginalElement->GetText()); |
togayan | 0:dfd5cfea7112 | 65 | } |
togayan | 0:dfd5cfea7112 | 66 | } |
togayan | 0:dfd5cfea7112 | 67 | } |
togayan | 0:dfd5cfea7112 | 68 | printf("\nlastBuildDate (original): %s\n", lastBuildDateOriginal); |
togayan | 0:dfd5cfea7112 | 69 | |
togayan | 0:dfd5cfea7112 | 70 | // Download Album |
togayan | 0:dfd5cfea7112 | 71 | GetFile(albumRssPath, albumRssUrl); |
togayan | 0:dfd5cfea7112 | 72 | |
togayan | 0:dfd5cfea7112 | 73 | // Summarize RSS |
togayan | 0:dfd5cfea7112 | 74 | addNewLine(tempPath, albumRssPath); |
togayan | 0:dfd5cfea7112 | 75 | summarizeRss(summaryPath, tempPath); |
togayan | 0:dfd5cfea7112 | 76 | |
togayan | 0:dfd5cfea7112 | 77 | // Obtain current lastBuildDate |
togayan | 0:dfd5cfea7112 | 78 | char lastBuildDateCurrent[32] = {0}; |
togayan | 0:dfd5cfea7112 | 79 | |
togayan | 0:dfd5cfea7112 | 80 | XMLDocument docCurrent; |
togayan | 0:dfd5cfea7112 | 81 | if(XML_SUCCESS != docCurrent.LoadFile(summaryPath)) |
togayan | 0:dfd5cfea7112 | 82 | { |
togayan | 0:dfd5cfea7112 | 83 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 84 | error("No current summary.xml in USB memory.\n"); |
togayan | 0:dfd5cfea7112 | 85 | } |
togayan | 0:dfd5cfea7112 | 86 | |
togayan | 0:dfd5cfea7112 | 87 | XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate"); |
togayan | 0:dfd5cfea7112 | 88 | if(NULL == lastBuildDateCurrentElement) |
togayan | 0:dfd5cfea7112 | 89 | { |
togayan | 0:dfd5cfea7112 | 90 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 91 | error("No \"lastBuildDate\" element in current RSS.\n"); |
togayan | 0:dfd5cfea7112 | 92 | } |
togayan | 0:dfd5cfea7112 | 93 | strcpy(lastBuildDateCurrent, lastBuildDateCurrentElement->GetText()); |
togayan | 0:dfd5cfea7112 | 94 | printf("\nlastBuildDate (current) : %s\n", lastBuildDateCurrent); |
togayan | 0:dfd5cfea7112 | 95 | |
togayan | 0:dfd5cfea7112 | 96 | |
togayan | 0:dfd5cfea7112 | 97 | char photoUrl[256] = {0}; |
togayan | 0:dfd5cfea7112 | 98 | char photoPath[32] = {0}; |
togayan | 0:dfd5cfea7112 | 99 | int photoNo = 1; |
togayan | 0:dfd5cfea7112 | 100 | XMLElement* itemElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item"); |
togayan | 0:dfd5cfea7112 | 101 | if(NULL == itemElement) |
togayan | 0:dfd5cfea7112 | 102 | { |
togayan | 0:dfd5cfea7112 | 103 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 104 | error("No \"enclosure\" element in current RSS.\n"); |
togayan | 0:dfd5cfea7112 | 105 | } |
togayan | 0:dfd5cfea7112 | 106 | strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url")); |
togayan | 0:dfd5cfea7112 | 107 | sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo); |
togayan | 0:dfd5cfea7112 | 108 | GetFile(photoPath, photoUrl); |
togayan | 0:dfd5cfea7112 | 109 | ++photoNo; |
togayan | 0:dfd5cfea7112 | 110 | |
togayan | 0:dfd5cfea7112 | 111 | while( (itemElement = itemElement->NextSiblingElement( "item" ) ) != NULL ) |
togayan | 0:dfd5cfea7112 | 112 | { |
togayan | 0:dfd5cfea7112 | 113 | strcpy(photoUrl, itemElement->FirstChildElement("enclosure")->Attribute("url")); |
togayan | 0:dfd5cfea7112 | 114 | sprintf(photoPath, "/usb/DCIM/%08d.jpg", photoNo); |
togayan | 0:dfd5cfea7112 | 115 | GetFile(photoPath, photoUrl); |
togayan | 0:dfd5cfea7112 | 116 | ++photoNo; |
togayan | 0:dfd5cfea7112 | 117 | } |
togayan | 0:dfd5cfea7112 | 118 | |
togayan | 0:dfd5cfea7112 | 119 | // Wait for the completion of writing to USB Mass Storage Device. |
togayan | 0:dfd5cfea7112 | 120 | wait(1); |
togayan | 0:dfd5cfea7112 | 121 | |
togayan | 0:dfd5cfea7112 | 122 | // FSUSB30 switches to HSD2 (External Device) |
togayan | 0:dfd5cfea7112 | 123 | printf("\nUSB host was switched to HSD2(External Device).\n"); |
togayan | 0:dfd5cfea7112 | 124 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 125 | |
togayan | 0:dfd5cfea7112 | 126 | // blink LED |
togayan | 0:dfd5cfea7112 | 127 | led1.startBlink(); |
togayan | 0:dfd5cfea7112 | 128 | ethGreen.startBlink(); |
togayan | 0:dfd5cfea7112 | 129 | |
togayan | 0:dfd5cfea7112 | 130 | while(true){} |
togayan | 0:dfd5cfea7112 | 131 | } |
togayan | 0:dfd5cfea7112 | 132 | |
togayan | 0:dfd5cfea7112 | 133 | int GetFile(const char *path, const char *url) |
togayan | 0:dfd5cfea7112 | 134 | { |
togayan | 0:dfd5cfea7112 | 135 | led2.startBlink(); |
togayan | 0:dfd5cfea7112 | 136 | ethYellow.startBlink(); |
togayan | 0:dfd5cfea7112 | 137 | printf("\nGetting %s\n", url); |
togayan | 0:dfd5cfea7112 | 138 | |
togayan | 0:dfd5cfea7112 | 139 | timer.stop(); |
togayan | 0:dfd5cfea7112 | 140 | timer.reset(); |
togayan | 0:dfd5cfea7112 | 141 | timer.start(); |
togayan | 0:dfd5cfea7112 | 142 | |
togayan | 0:dfd5cfea7112 | 143 | HTTPFile file(path); |
togayan | 0:dfd5cfea7112 | 144 | HTTPResult retGet = http.get(url, &file); |
togayan | 0:dfd5cfea7112 | 145 | if (retGet != HTTP_OK) |
togayan | 0:dfd5cfea7112 | 146 | { |
togayan | 0:dfd5cfea7112 | 147 | fsusb30s = 1; // HSD2 |
togayan | 0:dfd5cfea7112 | 148 | error("Error in http.get in GetFile(): %d\n", retGet); |
togayan | 0:dfd5cfea7112 | 149 | } |
togayan | 0:dfd5cfea7112 | 150 | file.clear(); |
togayan | 0:dfd5cfea7112 | 151 | |
togayan | 0:dfd5cfea7112 | 152 | timer.stop(); |
togayan | 0:dfd5cfea7112 | 153 | printf("timer.read_ms(): %d\n", timer.read_ms()); |
togayan | 0:dfd5cfea7112 | 154 | |
togayan | 0:dfd5cfea7112 | 155 | led2.finishBlink(); |
togayan | 0:dfd5cfea7112 | 156 | ethYellow.finishBlink(); |
togayan | 0:dfd5cfea7112 | 157 | return (0); |
togayan | 0:dfd5cfea7112 | 158 | } |
togayan | 0:dfd5cfea7112 | 159 | |
togayan | 0:dfd5cfea7112 | 160 | int addNewLine(const char* dstPath, const char* srcPath) |
togayan | 0:dfd5cfea7112 | 161 | { |
togayan | 0:dfd5cfea7112 | 162 | FILE* fpSrc = fopen(srcPath, "r"); |
togayan | 0:dfd5cfea7112 | 163 | if (fpSrc == NULL) |
togayan | 0:dfd5cfea7112 | 164 | { |
togayan | 0:dfd5cfea7112 | 165 | return -1; |
togayan | 0:dfd5cfea7112 | 166 | } |
togayan | 0:dfd5cfea7112 | 167 | |
togayan | 0:dfd5cfea7112 | 168 | FILE* fpDst = fopen(dstPath, "w"); |
togayan | 0:dfd5cfea7112 | 169 | if (fpDst == NULL) |
togayan | 0:dfd5cfea7112 | 170 | { |
togayan | 0:dfd5cfea7112 | 171 | return -1; |
togayan | 0:dfd5cfea7112 | 172 | } |
togayan | 0:dfd5cfea7112 | 173 | |
togayan | 0:dfd5cfea7112 | 174 | int src; |
togayan | 0:dfd5cfea7112 | 175 | int previous = '\0'; |
togayan | 0:dfd5cfea7112 | 176 | while( (src = fgetc(fpSrc)) != EOF ) |
togayan | 0:dfd5cfea7112 | 177 | { |
togayan | 0:dfd5cfea7112 | 178 | if(previous == '>' && src == '<') |
togayan | 0:dfd5cfea7112 | 179 | { |
togayan | 0:dfd5cfea7112 | 180 | fputc('\n', fpDst); |
togayan | 0:dfd5cfea7112 | 181 | } |
togayan | 0:dfd5cfea7112 | 182 | fputc(src, fpDst); |
togayan | 0:dfd5cfea7112 | 183 | previous = src; |
togayan | 0:dfd5cfea7112 | 184 | } |
togayan | 0:dfd5cfea7112 | 185 | |
togayan | 0:dfd5cfea7112 | 186 | fclose(fpDst); |
togayan | 0:dfd5cfea7112 | 187 | fclose(fpSrc); |
togayan | 0:dfd5cfea7112 | 188 | |
togayan | 0:dfd5cfea7112 | 189 | return 0; |
togayan | 0:dfd5cfea7112 | 190 | } |
togayan | 0:dfd5cfea7112 | 191 | |
togayan | 0:dfd5cfea7112 | 192 | int summarizeRss(const char* dstPath, const char* srcPath) |
togayan | 0:dfd5cfea7112 | 193 | { |
togayan | 0:dfd5cfea7112 | 194 | FILE* fpSrc = fopen(srcPath, "r"); |
togayan | 0:dfd5cfea7112 | 195 | if (fpSrc == NULL) |
togayan | 0:dfd5cfea7112 | 196 | { |
togayan | 0:dfd5cfea7112 | 197 | return -1; |
togayan | 0:dfd5cfea7112 | 198 | } |
togayan | 0:dfd5cfea7112 | 199 | |
togayan | 0:dfd5cfea7112 | 200 | FILE* fpDst = fopen(dstPath, "w"); |
togayan | 0:dfd5cfea7112 | 201 | if (fpDst == NULL) |
togayan | 0:dfd5cfea7112 | 202 | { |
togayan | 0:dfd5cfea7112 | 203 | return -1; |
togayan | 0:dfd5cfea7112 | 204 | } |
togayan | 0:dfd5cfea7112 | 205 | |
togayan | 0:dfd5cfea7112 | 206 | char* ptn[] = |
togayan | 0:dfd5cfea7112 | 207 | { |
togayan | 0:dfd5cfea7112 | 208 | "<?xml", |
togayan | 0:dfd5cfea7112 | 209 | "<rss", |
togayan | 0:dfd5cfea7112 | 210 | "<channel", |
togayan | 0:dfd5cfea7112 | 211 | "<lastBuildDate", |
togayan | 0:dfd5cfea7112 | 212 | "<item", |
togayan | 0:dfd5cfea7112 | 213 | "<enclosure", |
togayan | 0:dfd5cfea7112 | 214 | "</item", |
togayan | 0:dfd5cfea7112 | 215 | "</channel", |
togayan | 0:dfd5cfea7112 | 216 | "</rss" |
togayan | 0:dfd5cfea7112 | 217 | }; |
togayan | 0:dfd5cfea7112 | 218 | int ptnSize = sizeof(ptn) / sizeof(char*); |
togayan | 0:dfd5cfea7112 | 219 | |
togayan | 0:dfd5cfea7112 | 220 | char buff[1024] = {0}; |
togayan | 0:dfd5cfea7112 | 221 | while( fgets(buff, 1024, fpSrc) != NULL ) |
togayan | 0:dfd5cfea7112 | 222 | { |
togayan | 0:dfd5cfea7112 | 223 | for(int i = 0; i < ptnSize; ++i) |
togayan | 0:dfd5cfea7112 | 224 | { |
togayan | 0:dfd5cfea7112 | 225 | if( strncmp(buff, ptn[i], strlen(ptn[i])) == 0 ) |
togayan | 0:dfd5cfea7112 | 226 | { |
togayan | 0:dfd5cfea7112 | 227 | fputs(buff, fpDst); |
togayan | 0:dfd5cfea7112 | 228 | break; |
togayan | 0:dfd5cfea7112 | 229 | } |
togayan | 0:dfd5cfea7112 | 230 | } |
togayan | 0:dfd5cfea7112 | 231 | } |
togayan | 0:dfd5cfea7112 | 232 | |
togayan | 0:dfd5cfea7112 | 233 | fclose(fpDst); |
togayan | 0:dfd5cfea7112 | 234 | fclose(fpSrc); |
togayan | 0:dfd5cfea7112 | 235 | |
togayan | 0:dfd5cfea7112 | 236 | return 0; |
togayan | 0:dfd5cfea7112 | 237 | } |