/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.streams.instagram.api;
import org.apache.streams.instagram.config.InstagramConfiguration;
import org.apache.streams.instagram.pojo.UserRecentMediaRequest;
import org.apache.streams.instagram.provider.InstagramProviderUtil;
import org.apache.streams.jackson.StreamsJacksonMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.juneau.json.JsonParser;
import org.apache.juneau.rest.client.RestCall;
import org.apache.juneau.rest.client.RestCallException;
import org.apache.juneau.rest.client.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* Implementation of all instagram interfaces using juneau.
*/
public class Instagram implements Media, Users {
private static final Logger LOGGER = LoggerFactory.getLogger(Instagram.class);
private static Map<InstagramConfiguration, Instagram> INSTANCE_MAP = new ConcurrentHashMap<>();
private InstagramConfiguration configuration;
private ObjectMapper mapper;
private String rootUrl;
private CloseableHttpClient httpclient;
private InstagramOAuthRequestSigner oauthSigner;
RestClient restClient;
private Instagram(InstagramConfiguration configuration) throws InstantiationException {
this.configuration = configuration;
this.rootUrl = InstagramProviderUtil.baseUrl(configuration);
this.oauthSigner = new InstagramOAuthRequestSigner(configuration.getOauth());
this.httpclient = HttpClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectionRequestTimeout(5000)
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.setCookieSpec("easy")
.build()
)
.setMaxConnPerRoute(20)
.setMaxConnTotal(100)
.build();
this.restClient = new RestClient()
.setHttpClient(httpclient)
.setParser(JsonParser.class)
.setRootUrl(rootUrl);
this.mapper = StreamsJacksonMapper.getInstance();
}
/**
* getInstance of Instagram from InstagramConfiguration.
*
* @param configuration InstagramConfiguration
* @return Instagram
* @throws InstantiationException InstantiationException
*/
public static Instagram getInstance(InstagramConfiguration configuration) throws InstantiationException {
if (INSTANCE_MAP.containsKey(configuration) && INSTANCE_MAP.get(configuration) != null) {
return INSTANCE_MAP.get(configuration);
} else {
Instagram instagram = new Instagram(configuration);
INSTANCE_MAP.put(configuration, instagram);
return INSTANCE_MAP.get(configuration);
}
}
@Override
public UserInfoResponse self() {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// UserInfoResponse result = restUsers.lookupUser(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/self/");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
UserInfoResponse result = mapper.readValue(restResponseEntity, UserInfoResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public UserInfoResponse lookupUser(String user_id) {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// UserInfoResponse result = restUsers.lookupUser(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/" + user_id);
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
UserInfoResponse result = mapper.readValue(restResponseEntity, UserInfoResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public RecentMediaResponse selfMediaRecent(SelfRecentMediaRequest parameters) {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// RecentMediaResponse result = restUsers.selfMediaRecent(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/self/media/recent");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
if ( Objects.nonNull(parameters.getCount()) && StringUtils.isNotBlank(parameters.getCount().toString())) {
uriBuilder.addParameter("count", parameters.getCount().toString());
}
if ( Objects.nonNull(parameters.getMaxId()) && StringUtils.isNotBlank(parameters.getMaxId().toString())) {
uriBuilder.addParameter("max_id", parameters.getMaxId().toString());
}
if ( Objects.nonNull(parameters.getMinId()) && StringUtils.isNotBlank(parameters.getMinId().toString())) {
uriBuilder.addParameter("min", parameters.getMinId().toString());
}
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
RecentMediaResponse result = mapper.readValue(restResponseEntity, RecentMediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public RecentMediaResponse userMediaRecent(UserRecentMediaRequest parameters) {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// RecentMediaResponse result = restUsers.userMediaRecent(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/" + parameters.getUserId() + "/media/recent");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
if ( Objects.nonNull(parameters.getCount()) && StringUtils.isNotBlank(parameters.getCount().toString())) {
uriBuilder.addParameter("count", parameters.getCount().toString());
}
if ( Objects.nonNull(parameters.getMaxId()) && StringUtils.isNotBlank(parameters.getMaxId().toString())) {
uriBuilder.addParameter("max_id", parameters.getMaxId().toString());
}
if ( Objects.nonNull(parameters.getMinId()) && StringUtils.isNotBlank(parameters.getMinId().toString())) {
uriBuilder.addParameter("min", parameters.getMinId().toString());
}
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(1, 1000, new InstagramRetryHandler())
.getResponseAsString();
RecentMediaResponse result = mapper.readValue(restResponseEntity, RecentMediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public RecentMediaResponse selfMediaLiked(SelfLikedMediaRequest parameters) {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// RecentMediaResponse result = restUsers.selfMediaLiked(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/self/media/liked");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
if ( Objects.nonNull(parameters.getCount()) && StringUtils.isNotBlank(parameters.getCount().toString())) {
uriBuilder.addParameter("count", parameters.getCount().toString());
}
if ( Objects.nonNull(parameters.getMaxLikeId()) && StringUtils.isNotBlank(parameters.getMaxLikeId().toString())) {
uriBuilder.addParameter("max_like_id", parameters.getMaxLikeId().toString());
}
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
RecentMediaResponse result = mapper.readValue(restResponseEntity, RecentMediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public SearchUsersResponse searchUser(SearchUsersRequest parameters) {
try {
// TODO: use juneau @Remotable
// Users restUsers = restClient.getRemoteableProxy("/users", Users.class);
// SearchUsersResponse result = restUsers.searchUser(parameters);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/users/search");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
if ( Objects.nonNull(parameters.getCount()) && StringUtils.isNotBlank(parameters.getCount().toString())) {
uriBuilder.addParameter("count", parameters.getCount().toString());
}
if ( Objects.nonNull(parameters.getQ()) && StringUtils.isNotBlank(parameters.getQ().toString())) {
uriBuilder.addParameter("q", parameters.getQ().toString());
}
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
SearchUsersResponse result = mapper.readValue(restResponseEntity, SearchUsersResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public CommentsResponse comments(String media_id) {
try {
// TODO: use juneau @Remotable
// Media restMedia = restClient.getRemoteableProxy("/media", Media.class);
// CommentsResponse result = restMedia.comments(media_id);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/media/" + media_id + "/comments");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
uriBuilder.addParameter("media_id", media_id);
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
CommentsResponse result = mapper.readValue(restResponseEntity, CommentsResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public UsersInfoResponse likes(String media_id) {
try {
// TODO: use juneau @Remotable
// Media restMedia = restClient.getRemoteableProxy("/media", Media.class);
// UsersInfoResponse result = restMedia.likes(media_id);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/media/" + media_id + "/likes");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
UsersInfoResponse result = mapper.readValue(restResponseEntity, UsersInfoResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public MediaResponse lookupMedia(String media_id) {
try {
// TODO: use juneau @Remotable
// Media restMedia = restClient.getRemoteableProxy("/media", Media.class);
// MediaResponse result = restMedia.lookupMedia(media_id);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/media/" + media_id);
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
MediaResponse result = mapper.readValue(restResponseEntity, MediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public MediaResponse shortcode(String shortcode) {
try {
// TODO: use juneau @Remotable
// Media restMedia = restClient.getRemoteableProxy("/media", Media.class);
// MediaResponse result = restMedia.lookupMedia(media_id);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/media/shortcode/" + shortcode);
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
MediaResponse result = mapper.readValue(restResponseEntity, MediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
@Override
public SearchMediaResponse searchMedia(SearchMediaRequest parameters) {
try {
// TODO: use juneau @Remotable
// Media restMedia = restClient.getRemoteableProxy("/media", Media.class);
// SearchMediaResponse result = restMedia.lookupMedia(media_id);
// return result;
URIBuilder uriBuilder = new URIBuilder()
.setPath("/media/search");
uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
uriBuilder.addParameter("distance", parameters.getDistance().toString());
uriBuilder.addParameter("lat", parameters.getLat().toString());
uriBuilder.addParameter("lng", parameters.getLng().toString());
String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
uriBuilder.addParameter("sig", sig);
RestCall restCall = restClient.doGet(uriBuilder.build().toString());
try {
String restResponseEntity = restCall
.setRetryable(configuration.getRetryMax().intValue(), configuration.getRetrySleepMs().intValue(), new InstagramRetryHandler())
.getResponseAsString();
SearchMediaResponse result = mapper.readValue(restResponseEntity, SearchMediaResponse.class);
return result;
} catch (RestCallException ex) {
LOGGER.warn("RestCallException", ex);
}
} catch (IOException ex) {
LOGGER.warn("IOException", ex);
} catch (URISyntaxException ex) {
LOGGER.warn("URISyntaxException", ex);
} catch (Exception ex) {
LOGGER.warn("Exception", ex);
}
return null;
}
}