/
akolonin
/
aigents-java
Обзор
Документация
Войти
/
akolonin
/
aigents-java
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/main/java/net/webstructor/comm/goog/GApi.java
345 строк
14 KB
Anton Kolonin
2.7.7 RSS/Atom feeds supported; Siter refactoring in progress; Raw HTML caching (MEMORY OVERUSE RISK) #5 #19 #20
30 май 2020, 07:10
30 май 2020, 07:10
0a810c1
Код
Авторство
О чём код?
/* * MIT License * * Copyright (c) 2005-2020 by Anton Kolonin, Aigents® * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.webstructor.comm.goog; import java.io.IOException; import java.io.StringReader; import java.net.URLEncoder; import java.util.Date; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonReader; import net.webstructor.agent.Body; import net.webstructor.cat.HttpFileReader; import net.webstructor.comm.HTTP; import net.webstructor.comm.Socializer; import net.webstructor.core.Thing; import net.webstructor.data.SocialFeeder; import net.webstructor.peer.Profiler; /* https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get https://developers.google.com/identity/sign-in/web/server-side-flow https://developers.google.com/identity/sign-in/web/server-side-flow https://developers.google.com/+/web/api/rest/ https://developers.google.com/+/web/samples/javascript https://console.developers.google.com/apis/credentials?project=aigents-web-server https://www.googleapis.com/plus/v1/people http://stackoverflow.com/questions/13851157/oauth2-and-google-api-access-token-expiration-time activites by user: https://developers.google.com/+/web/api/rest/latest/activities/list https://www.googleapis.com/plus/v1/activities?query=aigents&access_token= https://www.googleapis.com/plus/v1/activities?orderBy=recent&maxResults=20&query=activityFeed&access_token= https://www.googleapis.com/plus/v1/people/113174676192873877221/activities/public?access_token= */ public class GApi extends Socializer { private String appId; private String appSecret; protected HttpFileReader reader;//TODO: move up to HTTP or fix native HTTP //https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens public GApi(Body body, String appId, String appSecret) { super(body); this.appId = appId; this.appSecret = appSecret; this.reader = new HttpFileReader(body); } public String name(){ return "google"; } public SocialFeeder getFeeder(String id, String token, String key, Date since, Date until, String[] areas) throws IOException{ if (appId == null)//fake instance for testing return null; GApiFeeder feeder = new GApiFeeder(this,body,id,body.languages,since,until); feeder.getFeed(token, key, since, until, new StringBuilder()); return feeder; } /*static Object[][] processComments(JsonObject object, String token, String user_id) throws IOException{ JsonObject replies = object.getJsonObject("replies"); int replies_count = replies.getInt("totalItems"); String repliesLink = getJsonString(replies,"selfLink",null); if (replies_count > 0 && repliesLink != null){ Object[][] comments = new Object[replies_count][]; String rurl = repliesLink+"?access_token="+token; String rstr = simpleGet(rurl); JsonReader jsonReader = Json.createReader(new StringReader(rstr)); JsonObject feed = jsonReader.readObject(); JsonArray items = feed.getJsonArray("items"); if (items.size() != replies_count){ //TODO: handle the case when comments are in the other place like youtube return null; } for (int i = 0; i < items.size(); i++){ JsonObject item = items.getJsonObject(i); JsonObject actor = item.getJsonObject("actor"); String id = getJsonString(actor,"id",""); String name = getJsonString(actor,"displayName",""); String content = getJsonString(item.getJsonObject("object"),"content",""); HashMap likers = new HashMap(); //TODO: get likes on comments - so far, it is not possible: //https://developers.google.com/+/web/api/rest/latest/comments#resource-representations boolean mylike = processLikes(item,token,user_id,"plusoners",likers); comments[i] = new Object[]{id,name,content,new Boolean(mylike),new Integer(likers.size())}; } jsonReader.close(); return comments; } return null; } //https://developers.google.com/+/web/api/rest/latest/comments/get#examples static boolean processLikes(JsonObject object, String token, String user_id, String set, HashMap likers) throws IOException{ boolean mylike = false; JsonObject likes = object.getJsonObject(set); int likes_count = likes.getInt("totalItems"); String likesLink = getJsonString(likes,"selfLink",null); if (likes_count > 0 && likesLink != null){ String rurl = likesLink+"?access_token="+token; //System.out.println(rurl); String rstr = simpleGet(rurl); //System.out.println(rstr); JsonReader jsonReader = Json.createReader(new StringReader(rstr)); JsonObject feed = jsonReader.readObject(); JsonArray items = feed.getJsonArray("items"); for (int i = 0; i < items.size(); i++){ JsonObject item = items.getJsonObject(i); String id = getJsonString(item,"id",null); String name = getJsonString(item,"displayName",null); if (id != null && name != null){ if (id.equals(user_id)) mylike = true; else likers.put(id, name); } } jsonReader.close(); } return mylike; } /*public static final String TIME_FORMAT = "yyyy-MM-dd"; //TODO: //- limit by period //- count my likes //- count likers and commenters //- count words public String reportOld(String user_id,String access_token) { Date since = Time.today(-365); StringWriter writer = new StringWriter(); writer.write("<html><body>Stay tuned to get your <b>Google</b> report!<br>For the time being, here is just brief summary of your activity:<br>"); try { String token = URLEncoder.encode(access_token,"UTF-8"); //String myurl = "https://www.googleapis.com/plus/v1/people/me?access_token="+token; //String me = simpleGet(myurl); //writer.write(me); writer.write("<br>"); String base = "https://www.googleapis.com/plus/v1/people/me/activities/public?maxResults=100&access_token="+token; String page = ""; for (;;){ String url = base + page; //System.out.println(url); String out = simpleGet(url); JsonReader jsonReader = Json.createReader(new StringReader(out)); JsonObject feed = jsonReader.readObject(); JsonArray items = feed.getJsonArray("items"); boolean days_over = false; for (int i = 0; i < items.size(); i++){ JsonObject item = items.getJsonObject(i); String date = getJsonString(item,"published"); Date date_day = Time.time(date,TIME_FORMAT); if (date_day.compareTo(since) < 0){ days_over = true; break; } //String verb = getJsonString(item,"verb"); String id = getJsonString(item,"id"); String uri = getJsonString(item,"url"); JsonObject object = item.getJsonObject("object"); String content = getJsonString(object,"content",""); //TODO: join content and annotation if both? if (AL.empty(content)) content = getJsonString(object,"annotation",""); Object[][] comments = processComments(object,token,user_id); int replies_count = comments == null ? 0 : comments.length; HashMap likers = new HashMap(); boolean mylike = processLikes(object,token,user_id,"plusoners",likers) || processLikes(object,token,user_id,"resharers",likers); String[] links = null; if (AL.empty(content)){ JsonArray attachments = object.getJsonArray("attachments"); links = new String[attachments.size()]; for (int j = 0; j < attachments.size(); j++){ JsonObject attachment = attachments.getJsonObject(j); String attachment_content = getJsonString(attachment,"content",""); if (AL.empty(attachment_content)) attachment_content = getJsonString(attachment,"displayName",""); if (AL.empty(content)) content = attachment_content; String link = getJsonString(attachment,"url",""); links[j] = link; } } //System.out.println(date+" : "+content); writer.write(date+" <a target=\"_blank\" href=\""+uri+"\">"+id+"</a>" +" likes:"+(mylike ? "I+":"+")+likers.size()+" comments:"+replies_count+"<br>" +content+"<br>"); if (links != null){ for (int j = 0; j < links.length; j++){ writer.write("<u><i><a href=\""+links[j]+"\" target=\"_blank\">"+links[j]+"</a></i></u><br>"); } } if (comments != null){ for (int j = 0; j < comments.length; j++){ writer.write("<i><small>>>" +comments[j][1] //peer +" likes:"+(((Boolean)comments[j][3]).booleanValue() ? "I+":"+")+"+"+comments[j][4] //likes +":"+comments[j][2] //content +"</small></i><br>"); } } if (likers.size() != 0){ for (Iterator it = likers.values().iterator(); it.hasNext();){ writer.write("<small>+"+it.next()+"</small><br>"); } } } //writer.write(out); if (days_over) break; String nextPageToken = getJsonString(feed,"nextPageToken"); if (AL.empty(nextPageToken)) break; page = "&pageToken="+nextPageToken; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } writer.write("</body></html>"); return writer.toString(); }*/ private static JsonObject getPrimary(JsonArray a){ if (a != null) for (int i = 0; i < a.size(); i++) { JsonObject o = a.getJsonObject(0); if (o.containsKey("metadata")) { JsonObject m = o.getJsonObject("metadata"); if (m.containsKey("primary") && m.getBoolean("primary")) return o; } } return null; } /** * Validates userId and appId against accessToken * @param userId * @param accessToken * @return true if userId is validated, false otherwise * @throws Exception */ public String[] verifyToken(String userId,String code) { if (userId.startsWith("test")) return new String[]{"test@gmail.com","tesname","testsurname",code,userId,code}; String url = ""; String out = ""; try { //NOTE!!! refresh_token here is received only upon the first authorization!!! //NOTE!!! to re-get refresh_token, need to remove the app from app settings: //https://security.google.com/settings/u/0/security/permissions //see more: //https://developers.google.com/identity/protocols/OAuth2WebServer //http://stackoverflow.com/questions/8942340/get-refresh-token-google-api //http://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token/10857806#10857806 //https://developers.google.com/identity/protocols/OAuth2WebServer#offline url = "https://accounts.google.com/o/oauth2/token"; String par = "code=" + URLEncoder.encode(code,"UTF-8") + "&redirect_uri=postmessage&client_id=" + URLEncoder.encode(appId,"UTF-8") + "&client_secret=" + URLEncoder.encode(appSecret,"UTF-8") + "&grant_type=authorization_code"; body.debug("Google request: " + url+ "/"+par); out = sendPost(url,par); body.debug("Google response: " + out); JsonReader jr = Json.createReader(new StringReader(out)); JsonObject jauth = jr.readObject(); String access_token = jauth.getString("access_token"); String refresh_token = jauth.containsKey("refresh_token") ? jauth.getString("refresh_token") : null; //int expires_in_seconds = jauth.getInt("expires_in"); jr.close(); //https://developers.google.com/people/api/rest/v1/people/get //curl "https://people.googleapis.com/v1/people/me?personFields=names&access_token=<token>" //curl "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,photos&access_token=<token>" //TODO: get conections for social report and friends profiling //https://developers.google.com/people/api/rest/v1/people.connections/list //curl "https://content-people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses,photos&access_token=<token>" url = "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses&access_token="+URLEncoder.encode(access_token,"UTF-8"); body.debug("Google request: " + url); out = simpleGet(url); body.debug("Google response: " + out); jr = Json.createReader(new StringReader(out)); JsonObject jme = jr.readObject(); JsonObject n = getPrimary(jme.getJsonArray("names")); String id = HTTP.getJsonString(n.getJsonObject("metadata").getJsonObject("source"),"id",""); String name = HTTP.getJsonString(n,"givenName"); String surname = HTTP.getJsonString(n,"familyName"); JsonObject e = getPrimary(jme.getJsonArray("emailAddresses")); String email = e == null ? id+"@google.com" : e.getString("value"); jr.close(); body.debug("Google login: " + name + " " + surname + " " + email + " " + access_token + " " + refresh_token); //TODO: remove hack replacing access_token with refresh_token!? return new String[]{email,name,surname,access_token,String.valueOf(id),refresh_token}; } catch (Exception e) { body.error("Google can't verify code url "+url+" out "+out, e); return null; } } @Override public Profiler getProfiler(Thing peer) { return new Profiler(body,this,peer,Body.google_id,Body.google_token,Body.google_key); } }