package io.loli.sc.api; import io.loli.sc.config.Config; import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.swing.JOptionPane; import org.apache.http.NameValuePair; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.map.ObjectMapper; public class ImgurAPI extends APITools implements API { private static final String CLIENT_ID = "497cc6f6f81c581"; private static final String CLIENT_SECRET = "4946a4382470ccee887599bc5bc506df3267f881"; private static final String AUTH_URL_PIN = "https://api.imgur.com/oauth2/authorize?client_id=" + CLIENT_ID + "&response_type=pin"; private static final String PIN_TO_TOKEN_URL = "https://api.imgur.com/oauth2/token"; private static final String UPLOAD = "https://api.imgur.com/3/upload"; private static final String REFRESH_TOKEN_URL = "https://api.imgur.com/oauth2/token"; private Config config; public void auth() throws UploadException { Desktop desktop = Desktop.getDesktop(); try { desktop.browse(new URI(AUTH_URL_PIN)); } catch (IOException | URISyntaxException e) { throw new UploadException(e); } } public String upload(File fileToUpload) throws UploadException { if (!fileToUpload.exists()) { JOptionPane.showMessageDialog(null, "图片文件不存在"); return ""; } ObjectMapper mapper = new ObjectMapper(); AccessToken token = null; // 如果token过期则重新获取 Date old = config.getImgurConfig().getDate(); Calendar cal = Calendar.getInstance(); cal.setTime(old); cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + 1); Date now = new Date(); if (cal.getTime().before(now)) { token = this .refreshToken(config.getImgurConfig().getRefreshToken()); } else { token = new AccessToken(); token.setAccess_token(config.getImgurConfig().getAccessToken()); } // post上传图片 String imageString = postFile(UPLOAD, fileToUpload, token.getAccess_token()); ImageInfo imageInfo = null; try { imageInfo = mapper.readValue(imageString, ImageInfo.class); } catch (IOException e) { throw new UploadException(e); } return imageInfo.getData().getLink(); } /** * 通过pin码获取token * * @param pin pin码 * @return token对象 * @throws UploadException */ public AccessToken pinToToken(String pin) throws UploadException { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.addAll(Arrays.asList(new NameValuePair[] { new BasicNameValuePair("client_id", CLIENT_ID), new BasicNameValuePair("client_secret", CLIENT_SECRET), new BasicNameValuePair("grant_type", "pin"), new BasicNameValuePair("pin", pin) })); String result = post(PIN_TO_TOKEN_URL, params); ObjectMapper mapper = new ObjectMapper(); AccessToken token = null; try { token = mapper.readValue(result, AccessToken.class); } catch (IOException e) { throw new UploadException(e); } return token; } /* * post上传文件 */ private String postFile(String postUrl, File imgFileToUpload, String accessToken) throws UploadException { CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost hp = new HttpPost(postUrl); hp.addHeader("Authorization", "Bearer " + accessToken); CloseableHttpResponse response = null; String result = null; try { MultipartEntityBuilder multiPartEntityBuilder = MultipartEntityBuilder .create(); multiPartEntityBuilder.addBinaryBody("image", imgFileToUpload); hp.setEntity(multiPartEntityBuilder.build()); response = httpclient.execute(hp); result = EntityUtils.toString(response.getEntity()); } catch (IOException e) { throw new UploadException(e); } return result; } /** * token过期后刷新 access token * * @param refreshToken 之前获取到的刷新用token * @return token对象 * @throws UploadException */ public AccessToken refreshToken(String refreshToken) throws UploadException { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.addAll(Arrays.asList(new NameValuePair[] { new BasicNameValuePair("refresh_token", refreshToken), new BasicNameValuePair("client_id", CLIENT_ID), new BasicNameValuePair("client_secret", CLIENT_SECRET), new BasicNameValuePair("grant_type", "refresh_token") })); ObjectMapper mapper = new ObjectMapper(); AccessToken token = null; try { token = mapper.readValue(post(REFRESH_TOKEN_URL, params), AccessToken.class); } catch (IOException e) { throw new UploadException(e); } return token; } public ImgurAPI() { } public ImgurAPI(Config config) { this.config = config; } public static class AccessToken { @JsonProperty private String access_token; @JsonProperty private int expires_in; @JsonProperty private String token_type; @JsonProperty private String scope; @JsonProperty private String refresh_token; @JsonProperty private String account_username; public AccessToken() { } public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public int getExpires_in() { return expires_in; } public void setExpires_in(int expires_in) { this.expires_in = expires_in; } public String getToken_type() { return token_type; } public void setToken_type(String token_type) { this.token_type = token_type; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } public String getRefresh_token() { return refresh_token; } public void setRefresh_token(String refresh_token) { this.refresh_token = refresh_token; } public String getAccount_username() { return account_username; } public void setAccount_username(String account_username) { this.account_username = account_username; } } static class ImageInfo { private boolean success; private int status; private Data data; static class Data { private String id; private String title; private String description; private int datetime; private String type; private boolean animated; private int width; private int height; private int size; private int views; private int bandwidth; private boolean favorite; private String nsfw; private String section; private String deletehash; private String link; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getDatetime() { return datetime; } public void setDatetime(int datetime) { this.datetime = datetime; } public String getType() { return type; } public void setType(String type) { this.type = type; } public boolean isAnimated() { return animated; } public void setAnimated(boolean animated) { this.animated = animated; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getViews() { return views; } public void setViews(int views) { this.views = views; } public int getBandwidth() { return bandwidth; } public void setBandwidth(int bandwidth) { this.bandwidth = bandwidth; } public boolean isFavorite() { return favorite; } public void setFavorite(boolean favorite) { this.favorite = favorite; } public String getNsfw() { return nsfw; } public void setNsfw(String nsfw) { this.nsfw = nsfw; } public String getSection() { return section; } public void setSection(String section) { this.section = section; } public String getDeletehash() { return deletehash; } public void setDeletehash(String deletehash) { this.deletehash = deletehash; } public String getLink() { return link; } public void setLink(String link) { this.link = link; } } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } } }