PocoXML, PocoNet & Flickr


#1

Hello All,

I was messing with the Poco libraries (http://pocoproject.org/poco/info/index.html) and thought it would be useful to share some of the code I wrote.

The following is a simple c++ program that gets a list of urls from Flickr via their web service API. This could be combined with other OF stuff, like the code discussed here: http://www.openframeworks.cc/forum/view-…-light=poco to load images from flickr into an ofTexture. I hope it’s useful. And if anyone sees mistakes or better-ways, please share.

  
  
#include "Poco/URIStreamOpener.h"  
#include "Poco/StreamCopier.h"  
#include "Poco/Path.h"  
#include "Poco/URI.h"  
#include "Poco/Exception.h"  
#include "Poco/Net/HTTPStreamFactory.h"  
#include "Poco/XML/XMLString.h"  
#include "Poco/DOM/DOMParser.h"  
#include "Poco/DOM/Document.h"  
#include "Poco/DOM/NodeIterator.h"  
#include "Poco/DOM/NodeFilter.h"  
#include "Poco/DOM/NamedNodeMap.h"  
  
#include <memory>  
#include <string>  
#include <vector>  
#include <iostream>  
  
using Poco::URIStreamOpener;  
using Poco::StreamCopier;  
using Poco::Path;  
using Poco::URI;  
using Poco::Exception;  
using Poco::Net::HTTPStreamFactory;  
using Poco::XML::XMLString;  
using Poco::XML::DOMParser;  
using Poco::XML::Document;  
using Poco::XML::NodeIterator;  
using Poco::XML::NodeFilter;  
using Poco::XML::Node;  
using Poco::XML::NamedNodeMap;  
  
static const std::string API_KEY = "[get yer own, son!]";  
static const std::string REST_URL = "[http://www.flickr.com/services/rest/?method=flickr.photos.getRecent&format=rest";](http://www.flickr.com/services/rest/?method=flickr.photos.getRecent&format=rest";)  
  
  
/** url looks like  
* [http://farm{farm-id}.static.flickr.com/{server-id}/{id}-{secret}.jpg](http://farm{farm-id}.static.flickr.com/{server-id}/{id}-{secret}.jpg)  
* or  
* [http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg](http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg)  
* or  
* [http://farm{farm-id}.static.flickr.com/{server-id}/{id}-{o-secret}-o.(jpg|gif|png)](http://farm{farm-id}.static.flickr.com/{server-id}/{id}-{o-secret}-o.(jpg|gif|png))  
 *   
 * see [http://www.flickr.com/services/api/misc.urls.html](http://www.flickr.com/services/api/misc.urls.html)  
*/  
std::string makeFlickrUrl(  
        Node* p_farm, Node* p_server, Node* p_id, Node* p_secret)   
{  
    if (p_farm && p_id && p_server && p_secret) {  
        return "[http://farm"](http://farm") + p_farm->getNodeValue() +   
               ".static.flickr.com/" + p_server->getNodeValue() +  
               "/" + p_id->getNodeValue() +  
               "_" + p_secret->getNodeValue() + ".jpg";  
    } else {  
        return "";  
    }  
}  
  
  
/*  
 * Take in a Flickr rest style api url that doesn't require   
 * authenticaiton and an api_key  
 */  
std::vector<std::string> getFlickrImageUrls(  
       const std::string& rest_url, const std::string& api_key)   
{  
    // Get REST style xml as string from flickr  
    std::auto_ptr<std::istream>  
    pStr(URIStreamOpener::defaultOpener().open(  
        rest_url +  "&api_key=" + api_key));  
    std::string str;  
    StreamCopier::copyToString(*pStr.get(), str);  
  
    // Set up XML Parser  
    DOMParser parser;  
    Document* pDoc = parser.parseString(str);  
    NodeIterator it(pDoc, NodeFilter::SHOW_ELEMENT);  
    Node* pNode = it.nextNode();  
    NamedNodeMap *nnm;  
    std::vector<std::string> urls;  
    std::string current_url;  
    while (pNode) {  
        nnm = pNode->attributes();  
        current_url = makeFlickrUrl(  
                                  nnm->getNamedItem("farm"),  
                                  nnm->getNamedItem("server"),  
                                  nnm->getNamedItem("id"),  
                                  nnm->getNamedItem("secret"));  
        if (current_url.length() > 0)  
            urls.push_back(current_url);  
        pNode = it.nextNode();  
    }  
    nnm->release();  
    return urls;  
}  
  
  
/* main */  
int main(int argc, char** argv)  
{  
    HTTPStreamFactory::registerFactory();  
    std::vector<std::string>   
        img_urls = getFlickrImageUrls(REST_URL, API_KEY);  
    for (std::vector<std::string>::const_iterator   
            iter = img_urls.begin();   
            iter != img_urls.end(); ++iter) {  
        std::cout << *iter << std::endl;  
    }  
}  
  

The formatting got a bit jacked by the narrow column. I hope it’s not too unreadable. Also, you need poco installed (On ubuntu it can be installed with apt-get), the following compile flags - -I/usr/include/Poco -I/usr/include/Poco/Net -I/usr/include/Poco/XML, and the following linker flags - -lPocoFoundation -lPocoNet -lPocoXML.

-Brian


#2

Hey Brian, thanks for this code, I took your advice and made

http://forum.openframeworks.cc/t/flickrscraperslideshow/1257/0

A flickr Scraper slideshow.

Thanks again,

JGL


#3

look cool,

i want to to the same but then with a different site, its called things speak. it has and api key but i don’t know how to take the data since its not an image but numbers. do you have a clue were i could start learning this. your example has a lot of code i don’t understand because im new to openframeworks.