简体   繁体   中英

How to access private photos through Flickrj Api?

I'm making an authenticated call to access photos through Flickr API. But I am only getting my public photos but not any private photos.

Given below is the code I'm using,

Flickr f;
 RequestContext requestContext;
 String frob = "";
 String token = "";

 DocumentBuilder xmlParser = null;


 public void getImages() throws ParserConfigurationException, IOException, SAXException, FlickrException, URISyntaxException, NoSuchAlgorithmException
 {

  DocumentBuilderFactory dcb = DocumentBuilderFactory.newInstance();
        try {
            this.xmlParser = dcb.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();
        }



  f = new Flickr("199d038ad88f6c6c377a4ab2341fb60f","4583b2386d3d6439",new REST()) ;
  Flickr.debugStream = false;
  requestContext = RequestContext.getRequestContext();
  AuthInterface authInterface = f.getAuthInterface();
  //PeopleInterface peopleInterface = f.getPeopleInterface();

  try {
  frob = authInterface.getFrob();
  } catch (FlickrException e) {
  e.printStackTrace();
  }
  System.out.println("frob: " + frob);


  java.net.URL url =authInterface.buildAuthenticationUrl(Permission.READ, frob);

  System.out.println(url.toExternalForm());

  Desktop desktop = Desktop.getDesktop();
  desktop.browse(url.toURI());


  // Get the response
  Auth auth = null ;
  String aLine = "";

  while(aLine.equals(""))
  {

   java.io.DataInputStream in = new java.io.DataInputStream(System.in);
   aLine = in.readLine();

  }

  auth =authInterface.getToken(frob);
  System.out.println("auth = "+auth);
  requestContext = RequestContext.getRequestContext();
  requestContext.setAuth(auth);
  f.setAuth(auth);

  UrlsInterface urlsInterface = f.getUrlsInterface();
  PhotosInterface photosInterface = f.getPhotosInterface();




  SearchParameters searchParams=new SearchParameters();
     searchParams.setSort(SearchParameters.INTERESTINGNESS_DESC);




     //Execute search with entered tags

     searchParams.setUserId(auth.getUser().getId());


     PhotoList photoList=photosInterface.search(searchParams, 10,1);


     if(photoList!=null){
        //Get search result and check the size of photo result
        for(int i=0;i<photoList.size();i++){
            Photo photo=(Photo)photoList.get(i);

           System.out.println(photo.getSmallSquareUrl());

        }

     }

To make authenticated calls with the flickrj api you need, in addition to your apiKey and secret, a third code, the token .

We get the token with a one-off first call, and then with the token in hand you can just use the api classes as you'd expect.

If you've ever used a flickr iOS/Android client you will recognise this: the first time you use the app, it sends you to a URL for you to authorise it. What it does is when you authorise it it gets this token key, and then its good to go. Without it, its not. Same for your java app.

I used this example implementation for this first step authentication, with a couple of modifications though as I am working in a Spring MVC app, not a desktop app. Remember that you only run this once, and the only point of this is to get the token key.

https://github.com/mohlendo/flickrj/blob/master/examples/AuthExample.java

Line 55:
frob = authInterface.getFrob();

The only purpose of a frob is to use it to construct the authentication URL, see line 60:
URL url = authInterface.buildAuthenticationUrl(Permission.DELETE, frob);

I did this in a spring MVC app, not a desktop app, so after line 60 I instead printed the URL to System.out and then paused the programme for a minute with Thread.sleep(60000);

That gave me enough time to copy-paste the URL from my console to a browser and click "OK allow my app to use my flickr account".

Straight after that, when the program resumes all I cared was line 70 that prints the token to the console.

With the token in hand, the authorisation is complete and I was set to use the Flickrj api.

With the 3 keys in hand (apiKey, secret, token) here is my Service class with a static method to create a Flickr object.

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.xml.parsers.ParserConfigurationException;

import com.aetrion.flickr.Flickr;
import com.aetrion.flickr.REST;
import com.aetrion.flickr.RequestContext;
import com.aetrion.flickr.auth.Auth;
import com.aetrion.flickr.auth.Permission;
import com.aetrion.flickr.util.IOUtilities;

public class FlickrjService {

    private static Flickr flickr;

    public static Flickr getFlickr() throws ParserConfigurationException, IOException {
        InputStream in = null;
        Properties properties;
        try {
            in = FlickrjService.class.getResourceAsStream("/flickrj.properties");
            properties = new Properties();
            properties.load(in);
        } finally {
            IOUtilities.close(in);
        }

        flickr = new Flickr(properties.getProperty("flickrj.apiKey"), properties.getProperty("flickrj.secret"), new REST("www.flickr.com"));
        RequestContext requestContext = RequestContext.getRequestContext();
        Auth auth = new Auth();
        auth.setPermission(Permission.READ);
        auth.setToken(properties.getProperty("flickrj.token"));
        requestContext.setAuth(auth);
        Flickr.debugRequest = false;
        Flickr.debugStream = false;
        return flickr;
    }
}

It is possible to access private data by editing flickrj.

I added the auth_token parameter in com.aetrion.flickr.photos.PhotosInterface :

public PhotoList search(SearchParameters params, int perPage, int page)
    throws IOException, SAXException, FlickrException {
    PhotoList photos = new PhotoList();

    List parameters = new ArrayList();
    parameters.add(new Parameter("method", METHOD_SEARCH));
    parameters.add(new Parameter("api_key", apiKey));

    parameters.addAll(params.getAsParameters());


    if (perPage > 0) {
        parameters.add(new Parameter("per_page", "" + perPage));
    }
    if (page > 0) {
        parameters.add(new Parameter("page", "" + page));
    }
    //
    String token = RequestContext.getRequestContext().getAuth().getToken();
    if (token != null)
      parameters.add(
        new Parameter(
          "auth_token", 
          RequestContext.getRequestContext().getAuth().getToken()
        )
      );
    //
    parameters.add(
        new Parameter(
            "api_sig",
            AuthUtilities.getSignature(sharedSecret, parameters)
        )
    );

    Response response = transport.get(transport.getPath(), parameters);

with this change, I was able to get my private photos.

the flickr api docs say, that " Every authenticated call requires both the auth_token and api_sig arguments ".. and that was missing.

I took the idea from there: link text and used a servlet to access flickr.

I don't know if this will help you, but I was having a similar problem with seeing only public photos and have since got it working.

I'd downloaded the flickrapi-1.2.zip from: http://sourceforge.net/projects/flickrj/files/ and was using flickrapi-1.2.jar in my webapp.

Flickr.debugRequest was showing the GET request, but it never included "auth_token", "api_sig", etc. parameters that AuthInterface checkToken (for example) successfully forces on the request.

Anyway, so just today I downloaded the source from:

flickrj.cvs.sourceforge.net/flickrj/

(You can see the revision history at: flickrj.cvs.sourceforge.net/viewvc/flickrj/api/build.properties?view=log if you're interested.)

I built the jar locally, included that in the web app and could see private photos.

I haven't spent the time to investigate further about what the exact problem was...need to use it for something :)

I don't know if that will help you, but that find is the only thing separating me from insanity.

I managed to solve this problem by following a different approach.

This is how i solved this. Instead of using the GET method I used the getList method in photoSetsInterface (photoSetsInterface.getList(auth.getUser().getId()).getPhotosets()) .For this method you can pass the auth_token as an input parameter. Therefore it gives you all the photo sets. Then I took each photoset and retrived images under all privacy levels.

And then you can take all the photos that are not in a set by using the getNotInSet method in PhotosInterface. getNotInSet method returns all the photos not in a set regardless of the privacy level.

You can find the sample code in my blog .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM