diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java index 9723152..f5e37f7 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java @@ -10,7 +10,8 @@ public enum ApiVersion { VERSION_5_7("5.7"), VERSION_5_8("5.8"), VERSION_5_21("5.21"), - VERSION_5_27("5.27"); + VERSION_5_27("5.27"), + VERSION_5_33("5.33"); private String version; diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java index 628b7e9..ed3f9c4 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java @@ -18,7 +18,7 @@ import java.io.Serializable; /** - * Model class representing audio.
+ * Model class representing audio.
* See definition of this object at http://vk.com/dev/audio_object * * @author vkolodrevskiy diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java new file mode 100644 index 0000000..b601782 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java @@ -0,0 +1,66 @@ +package org.springframework.social.vkontakte.api; + +import org.springframework.social.vkontakte.api.attachment.Attachment; +import org.springframework.util.StringUtils; + +import java.util.Date; +import java.util.List; + +/** + * Model class representing a comment on a post on a user wall or community wall. + * + * @see Comment object | Developers | VK + */ +public class Comment { + private long id; + private long fromId; + private Date date; + private String text; + private long replyToUser; + private long replyToComment; + private Post.Likes likes; + private List attachments; + + public long getFromId() { + return fromId; + } + + public Date getDate() { + return date; + } + + public String getText() { + return text; + } + + public long getId() { + return id; + } + + public long getReplyToUser() { + return replyToUser; + } + + public long getReplyToComment() { + return replyToComment; + } + + public Post.Likes getLikes() { + return likes; + } + + public List getAttachments() { + return attachments; + } + + @Override + public String toString() { + return "Comment{" + + "id='" + id + '\'' + + ", date=" + date + + ", text='" + text + '\'' + + ", likes=" + likes + + ", attachments=" + (attachments == null ? null : StringUtils.collectionToDelimitedString(attachments, ",\n")) + + '}'; + } +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java new file mode 100644 index 0000000..34ace75 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java @@ -0,0 +1,42 @@ +package org.springframework.social.vkontakte.api; + +import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery; + +import java.util.List; + +/** + * Model class representing a response that contains a list of comments on a post on a user wall or community wall. + * + * @see IWallOperations#getComments(CommentsQuery) + */ +public class CommentsResponse { + private final long count; + private final List comments; + private final List profiles; + private final List groups; + private final Long realOffset; + + public CommentsResponse(List comments, long count, Long realOffset, List profiles, List groups) { + this.comments = comments; + this.count = count; + this.realOffset = realOffset; + this.groups = groups; + this.profiles = profiles; + } + + public long getCount() { + return count; + } + + public long getRealOffset() { + return realOffset; + } + + public List getComments() { + return comments; + } + + public List getProfiles() { + return profiles; + } +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java new file mode 100644 index 0000000..d1c4deb --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.springframework.social.vkontakte.api; + +/** + * Counters. + * https://vk.com/dev/fields + * + * @author dIsoVi + */ +public class Counters { + private int albums; + private int videos; + private int audios; + private int notes; + private int photos; + private int groups; + private int gifts; + private int friends; + private int onlineFriends; + private int mutualFriends; + private int userPhotos; + private int userVideos; + private int followers; + private int subscriptions; + private int pages; + + public int getUserVideos() { + return userVideos; + } + + public int getUserPhotos() { + return userPhotos; + } + + public int getAlbums() { + return albums; + } + + public int getVideos() { + return videos; + } + + public int getAudios() { + return audios; + } + + public int getNotes() { + return notes; + } + + public int getPhotos() { + return photos; + } + + public int getGroups() { + return groups; + } + + public int getGifts() { + return gifts; + } + + public int getFriends() { + return friends; + } + + public int getOnlineFriends() { + return onlineFriends; + } + + public int getMutualFriends() { + return mutualFriends; + } + + public int getFollowers() { + return followers; + } + + public int getSubscriptions() { + return subscriptions; + } + + public int getPages() { + return pages; + } +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java index a42cc76..6e788ab 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java @@ -15,6 +15,10 @@ */ package org.springframework.social.vkontakte.api; +import org.springframework.social.vkontakte.api.impl.json.VKArray; +import org.springframework.social.vkontakte.api.vkenums.FriendsOrder; +import org.springframework.social.vkontakte.api.vkenums.NameCase; + import java.util.List; /** @@ -22,7 +26,7 @@ * @author vkolodrevskiy */ public interface IFriendsOperations { - public final static String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name"; + String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name"; /** * Retrieves a list of user friends for the current authorized user. * @return a list of user friends profiles. @@ -30,7 +34,7 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List get(); + VKArray get(); /** * Retrieves a list of user friends for the current authorized user. @@ -40,7 +44,7 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List get(String fields); + VKArray get(String fields); /** * Retrieves a list of user friends for specified user unique identifier. @@ -50,7 +54,7 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List get(Long userId); + VKArray get(Long userId); /** * Retrieves a list of user friends for specified user unique identifier. @@ -61,12 +65,27 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List get(Long userId, String fields); + VKArray get(Long userId, String fields); + + /** + * Retrieves a list of user friends for specified user unique identifier. + * @param userId user unique identifier for which to get friends. + * @param fields VKontakte fields to retrieve, comma-delimited. + * @param count Number(positive number) of friends to return. If you want to return all friends pass negative number. + * @param offset Offset(positive number) needed to return a specific subset of friends. + * @return a list of user friends profiles. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. + */ + VKArray get(Long userId, String fields, int count, int offset); /** * Retrieves a list of user friends for specified user unique identifier. * @param userId user unique identifier for which to get friends. * @param fields VKontakte fields to retrieve, comma-delimited. + * @param order sort order. + * @param nameCase case for declension of user name and surname. * @param count Number(positive number) of friends to return. If you want to return all friends pass negative number. * @param offset Offset(positive number) needed to return a specific subset of friends. * @return a list of user friends profiles. @@ -74,7 +93,7 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List get(Long userId, String fields, int count, int offset); + VKArray get(Long userId, String fields, FriendsOrder order, NameCase nameCase, int count, int offset); /** * Retrieves a list of user friends id's that are online for the current authorized user. @@ -88,7 +107,7 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List> getOnline(boolean onlineMobile, int count, int offset); + List> getOnline(boolean onlineMobile, int count, int offset); /** * Retrieves a list of user friends that are online for specified user unique identifier. @@ -103,5 +122,5 @@ public interface IFriendsOperations { * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - public List> getOnline(Long userId, boolean onlineMobile, int count, int offset); + List> getOnline(Long userId, boolean onlineMobile, int count, int offset); } \ No newline at end of file diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java index 9680c30..9bfc0c4 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java @@ -15,53 +15,75 @@ */ package org.springframework.social.vkontakte.api; +import org.springframework.social.vkontakte.api.vkenums.NameCase; + import java.util.List; /** * User operations. + * * @author vkolodrevskiy */ public interface IUsersOperations { - public final static String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name"; + String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name"; + /** - * Retrieves the profile for the authenticated user. - * @return the user's profile information. - * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. - * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + * Retrieves the profile for the authenticated user. + * + * @return the user's profile information. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. - */ - VKontakteProfile getUser(); + */ + VKontakteProfile getUser(); /** * Retrieves the profile for the authenticated user. + * * @param fields VKontakte fields to retrieve, comma-delimited. * @return the user's profile information. - * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. - * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ VKontakteProfile getUser(String fields); - /** - * Retrieves profiles for specified user unique identifiers. - * @param userIds VKontakte user profile unique identifiers, for which to gt data. - * If null is passed user profile or the current user will be returned. - * @return the user's profile information. - * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. - * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + /** + * Retrieves profiles for specified user unique identifiers. + * + * @param userIds VKontakte user profile unique identifiers, for which to gt data. + * If {@code null} is passed user profile or the current user will be returned. + * @return the user's profile information. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. - */ - List getUsers(List userIds); + */ + List getUsers(List userIds); /** * Retrieves profiles for specified user unique identifiers. + * * @param userIds VKontakte user profile unique identifiers, for which to gt data. - * @param fields VKontakte fields to retrieve, comma-delimited. - * If null is passed user profile or the current user will be returned. + * @param fields VKontakte fields to retrieve, comma-delimited. + * If {@code null} is passed user profile or the current user will be returned. + * @return the user's profile information. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. + */ + List getUsers(List userIds, String fields); + + /** + * Retrieves profiles for specified user unique identifiers. + * + * @param userIds VKontakte user profile unique identifiers, for which to gt data. + * @param fields VKontakte fields to retrieve, comma-delimited. + * If {@code null} is passed user profile or the current user will be returned. + * @param nameCase case for declension of user name and surname. * @return the user's profile information. - * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. - * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. + * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte. + * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token. * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. */ - List getUsers(List userIds, String fields); + List getUsers(List userIds, String fields, NameCase nameCase); } \ No newline at end of file diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java index e0fa040..a37d123 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java @@ -20,5 +20,18 @@ * @author dIsoVi */ public interface IUtilsOperations { - public VKObject resolveScreenName(String screenName); + /** + * utils.resolveScreenName + * Detects a type of object (e.g., user, community, application) and its ID by screen name. + * @param screenName Screen name of the user, community (e.g., apiclub, andrew, or rules_of_war), or application. + * @return an object with type and id + */ + VKObject resolveScreenName(String screenName); + + /** + * A universal method for calling a sequence of other methods while saving and filtering interim results. + * @param code - Algorithm code in VKScript (https://vk.com/dev/execute) + * @return data requested by the algorithm + */ + VKGenericResponse execute(String code); } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java index b5a93b5..d7e9589 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java @@ -15,6 +15,8 @@ */ package org.springframework.social.vkontakte.api; +import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery; + import java.util.List; /** @@ -62,4 +64,12 @@ public interface IWallOperations { PostStatus post(PostData postData); + /** + * Returns a response that contains a list of comments on a post on a user wall or community wall. + * + * @param query {@link CommentsQuery} + * @return a {@link CommentsResponse}, object representing the response on query of comments on a post on a user's or community's wall + * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error. + */ + CommentsResponse getComments(CommentsQuery query); } \ No newline at end of file diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java index bd1c262..f14f8bc 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java @@ -23,50 +23,67 @@ * @author vkolodrevskiy */ public interface VKontakte extends ApiBinding { - /** - * API for performing operations on VKontakte user profiles. - */ + * API for performing operations on VKontakte user profiles. + * + * @return {@link IUsersOperations} + */ public IUsersOperations usersOperations(); - /** - * API for performing operations on feeds. - */ + /** + * API for performing operations on feeds. + * + * @return {@link IWallOperations} + */ public IWallOperations wallOperations(); - /** - * API for performing operations with a user's set of friends. - */ + /** + * API for performing operations with a user's set of friends. + * + * @return {@link IFriendsOperations} + */ public IFriendsOperations friendsOperations(); /** * API for performing secure operations. + * + * @return {@link ISecureOperations} */ public ISecureOperations secureOperations(); /** * API for performing operations with a location info. + * + * @return {@link ILocationOperations} */ public ILocationOperations locationOperations(); /** * API for performing operations with audio. + * + * @return {@link IAudioOperations} */ public IAudioOperations audioOperations(); /** * API for performing operations with groups. + * + * @return {@link IGroupsOperations} */ public IGroupsOperations groupsOperations(); /** * API for performing operations with newsfeed. + * + * @return {@link INewsFeedOperations} */ public INewsFeedOperations newsFeedOperations(); /** * API for performing operations with utils. + * + * @return {@link IUtilsOperations} */ public IUtilsOperations utilsOperations(); } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java index c8edcab..c61343f 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java @@ -23,6 +23,12 @@ * @author vkolodrevskiy */ public class VKontakteProfile { + public VKontakteProfile(long id) { + this.id = id; + } + + public VKontakteProfile() { + } private final static String PROFILE_URL_EXTESTION = "http://vk.com/"; private long id; @@ -55,6 +61,7 @@ public class VKontakteProfile { private String facebook; private String facebookName; private String twitter; + private String instagram; private String site; private String status; private int commonCount; @@ -84,6 +91,23 @@ public class VKontakteProfile { private List relatives; private VKontakteProfile relationPartner; private LastSeen lastSeen; + private Counters counters; + + public String getInstagram() { + return instagram; + } + + public void setInstagram(String instagram) { + this.instagram = instagram; + } + + public Counters getCounters() { + return counters; + } + + public void setCounters(Counters counters) { + this.counters = counters; + } public String getDeactivated() { return deactivated; @@ -551,6 +575,9 @@ public void setQuotes(String quotes) { } public String getProfileURL() { + if (screenName == null) { + return PROFILE_URL_EXTESTION + "id" + id; + } return PROFILE_URL_EXTESTION + screenName; } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java index 4c3e3d7..d4d9fc2 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java @@ -26,6 +26,7 @@ import org.springframework.social.vkontakte.api.VKontakteErrorException; import org.springframework.social.vkontakte.api.impl.json.VKArray; import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; import java.net.URI; import java.util.ArrayList; @@ -74,6 +75,13 @@ protected URI makeOperationURL(String method, Properties params, ApiVersion apiV return uri.build(); } + protected URI makeOperationPOST(String method, MultiValueMap data, ApiVersion apiVersion) { + URIBuilder uri = URIBuilder.fromUri(VK_REST_URL + method); + data.set("access_token", accessToken); + data.set("v", apiVersion.toString()); + return uri.build(); + } + protected void preProcessURI(URIBuilder uri) { // add access_token // TODO: for some methods we do not need access token, so think about it. @@ -100,10 +108,11 @@ protected VKArray deserializeArray(VKGenericResponse response, Class i /** * for responses of VK API 5.0+ - * @param response - * @param itemClass - * @param - * @return + * + * @param response {@link VKGenericResponse response} + * @param itemClass class of the item + * @param item type + * @return array */ protected VKArray deserializeVK50ItemsResponse(VKGenericResponse response, Class itemClass) { checkForError(response); @@ -111,7 +120,7 @@ protected VKArray deserializeVK50ItemsResponse(VKGenericResponse response JsonNode itemsNode = jsonNode.get("items"); Assert.isTrue(itemsNode.isArray()); int count = jsonNode.get("count").asInt(); - return new VKArray(count, deserializeItems((ArrayNode)itemsNode, itemClass)); + return new VKArray(count, deserializeItems((ArrayNode) itemsNode, itemClass)); } protected List deserializeItems(ArrayNode items, Class itemClass) { diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java index 7ad30cb..8ecf0c2 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java @@ -17,7 +17,14 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.social.vkontakte.api.*; +import org.springframework.social.vkontakte.api.ApiVersion; +import org.springframework.social.vkontakte.api.IFriendsOperations; +import org.springframework.social.vkontakte.api.VKGenericResponse; +import org.springframework.social.vkontakte.api.VKontakteProfile; +import org.springframework.social.vkontakte.api.impl.json.VKArray; +import org.springframework.social.vkontakte.api.vkenums.FriendsOrder; +import org.springframework.social.vkontakte.api.vkenums.NameCase; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import java.net.URI; @@ -38,23 +45,27 @@ public FriendsTemplate(RestTemplate restTemplate, String accessToken, ObjectMapp this.restTemplate = restTemplate; } - public List get(String fields) { + public VKArray get(String fields) { return get(null, fields); } - public List get() { + public VKArray get() { return get(null, IFriendsOperations.DEFAULT_FIELDS); } - public List get(Long userId) { + public VKArray get(Long userId) { return get(userId, IFriendsOperations.DEFAULT_FIELDS); } - public List get(Long userId, String fields) { + public VKArray get(Long userId, String fields) { return get(userId, fields, -1, -1); } - public List get(Long userId, String fields, int count, int offset) { + public VKArray get(Long userId, String fields, int count, int offset) { + return get(userId, fields, FriendsOrder.NONE, NameCase.nom, count, offset); + } + + public VKArray get(Long userId, String fields, FriendsOrder order, NameCase nameCase, int count, int offset) { requireAuthorization(); Properties props = new Properties(); @@ -67,13 +78,22 @@ public List get(Long userId, String fields, int count, int off if (offset != -1) { props.put("offset", offset); } - props.put("fields", fields); + if (!StringUtils.isEmpty(fields)) { + props.put("fields", fields); + } + if (order != FriendsOrder.NONE) { + props.put("order", order.toString()); + } + if (nameCase != NameCase.nom) { + props.put("name_case", nameCase.toString()); + } + URI uri = makeOperationURL("friends.get", props, ApiVersion.VERSION_5_27); VKGenericResponse response = restTemplate.getForObject(uri, VKGenericResponse.class); checkForError(response); - return deserializeVK50ItemsResponse(response, VKontakteProfile.class).getItems(); + return deserializeVK50ItemsResponse(response, VKontakteProfile.class); } public List> getOnline(boolean onlineMobile, int count, int offset) { diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java index 8f7b8fe..acdb7e3 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java @@ -20,11 +20,13 @@ import org.springframework.social.vkontakte.api.IUsersOperations; import org.springframework.social.vkontakte.api.VKontakteProfile; import org.springframework.social.vkontakte.api.VKontakteProfiles; +import org.springframework.social.vkontakte.api.vkenums.NameCase; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.net.URI; import java.util.List; -import java.util.Properties; /** * User operations. @@ -39,35 +41,40 @@ public UsersTemplate(RestTemplate restTemplate, String accessToken, ObjectMapper this.restTemplate = restTemplate; } - public List getUsers(List userIds, String fields) { + public List getUsers(List userIds) { + return getUsers(userIds, null); + } + + public List getUsers(List userIds, String fields) { + return getUsers(userIds, fields, NameCase.nom); + } + + public List getUsers(List userIds, String fields, NameCase nameCase) { requireAuthorization(); - Properties props = new Properties(); + MultiValueMap data = new LinkedMultiValueMap(); - StringBuilder uids = new StringBuilder(); - if(userIds != null) { - for(Long uid : userIds) { - if(uids.toString().isEmpty()) - uids.append(uid); - else uids.append(",").append(uid); + if (userIds != null) { + StringBuilder sb = new StringBuilder(); + for(String uid : userIds){ + sb.append(uid).append(","); } - props.put("user_ids", uids.toString()); + sb.deleteCharAt(sb.length() - 1); + data.set("user_ids", sb.toString()); + } + if (nameCase != NameCase.nom) { + data.set("name_case", nameCase.toString()); } - props.put("fields", fields != null? fields: IUsersOperations.DEFAULT_FIELDS); + data.set("fields", fields != null? fields: IUsersOperations.DEFAULT_FIELDS); // see documentation under http://vk.com/dev/users.get - URI uri = makeOperationURL("users.get", props, ApiVersion.VERSION_5_27); - - VKontakteProfiles profiles = restTemplate.getForObject(uri, VKontakteProfiles.class); + URI uri = makeOperationPOST("users.get", data, ApiVersion.VERSION_5_27); + VKontakteProfiles profiles = restTemplate.postForObject(uri, data, VKontakteProfiles.class); checkForError(profiles); return profiles.getProfiles(); } - public List getUsers(List userIds) { - return getUsers(userIds, null); - } - public VKontakteProfile getUser() { return getUsers(null).get(0); } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java index b8e3ba4..f4b459d 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java @@ -5,6 +5,8 @@ import org.springframework.social.vkontakte.api.IUtilsOperations; import org.springframework.social.vkontakte.api.VKGenericResponse; import org.springframework.social.vkontakte.api.VKObject; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.net.URI; @@ -17,8 +19,8 @@ public class UtilsTemplate extends AbstractVKontakteOperations implements IUtilsOperations { private final RestTemplate restTemplate; - public UtilsTemplate(RestTemplate restTemplate, ObjectMapper objectMapper) { - super(false, null, objectMapper); + public UtilsTemplate(RestTemplate restTemplate, String accessToken, ObjectMapper objectMapper, boolean isAuthorizedForUser) { + super(isAuthorizedForUser, accessToken, objectMapper); this.restTemplate = restTemplate; } @@ -29,4 +31,14 @@ public VKObject resolveScreenName(String screenName) { VKGenericResponse response = restTemplate.getForObject(uri, VKGenericResponse.class); return deserializeVK50Item(response, VKObject.class); } + + // TODO: give user the ability to deserialize response by setting template class? + public VKGenericResponse execute(String code) { + MultiValueMap data = new LinkedMultiValueMap(); + data.set("code", code); + URI uri = makeOperationPOST("execute", data, ApiVersion.VERSION_5_27); + VKGenericResponse response = restTemplate.postForObject(uri, data, VKGenericResponse.class); + checkForError(response); + return response; + } } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java index 4403791..6807c82 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java @@ -103,7 +103,7 @@ private void initSubApis() { audioOperations = new AudioTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized()); groupsOperations = new GroupsTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized()); newsFeedOperations = new NewsFeedTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized()); - utilsOperations = new UtilsTemplate(getRestTemplate(), objectMapper); + utilsOperations = new UtilsTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized()); } public IUsersOperations usersOperations() { diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java index 6880d04..dc84823 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java @@ -16,8 +16,13 @@ package org.springframework.social.vkontakte.api.impl; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import org.springframework.social.UncategorizedApiException; import org.springframework.social.vkontakte.api.*; +import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery; +import org.springframework.social.vkontakte.api.impl.wall.CommunityWall; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.io.IOException; @@ -27,6 +32,7 @@ /** * {@link org.springframework.social.vkontakte.api.IWallOperations} implementation. + * * @author vkolodrevskiy */ public class WallTemplate extends AbstractVKontakteOperations implements IWallOperations { @@ -90,4 +96,65 @@ public PostStatus post(PostData postData) { return response.getStatus(); } + + public CommentsResponse getComments(CommentsQuery query) { + MultiValueMap data = new LinkedMultiValueMap(); + + if (query.owner instanceof CommunityWall) { + data.set("owner_id", "-" + String.valueOf(query.owner.getId())); + } else { + data.set("owner_id", String.valueOf(query.owner.getId())); + } + + data.set("post_id", String.valueOf(query.postId)); + + if (query.needLikes) { + data.set("need_likes", "1"); + } + + if (query.startCommentId != null && query.startCommentId > 0) { + data.set("start_comment_id", query.startCommentId.toString()); + } + + if (query.offset != null && query.offset > 0) { + data.set("offset", query.offset.toString()); + } + + if (query.count != null && query.count > 0) { + data.set("count", query.count.toString()); + } + + if (query.sort != null) { + data.set("sort", query.sort.toString()); + } + + if (query.previewLength != null && query.previewLength > 0) { + data.set("preview_length", query.previewLength.toString()); + } else { + //Specify 0 as it does not want to truncate comments. + data.set("preview_length", "0"); + } + + if (query.extended) { + data.set("extended", "1"); + } + + URI uri = makeOperationPOST("wall.getComments", data, ApiVersion.VERSION_5_33); + VKGenericResponse response = restTemplate.postForObject(uri, data, VKGenericResponse.class); + checkForError(response); + + List comments = deserializeVK50ItemsResponse(response, Comment.class).getItems(); + List profiles = null; + List groups = null; + if (query.extended) { + profiles = deserializeItems((ArrayNode) response.getResponse().get("profiles"), VKontakteProfile.class); + groups = deserializeItems((ArrayNode) response.getResponse().get("groups"), Group.class); + } + long count = response.getResponse().get("count").asLong(); + Long realOffset = null; + if (query.startCommentId != null) { + realOffset = response.getResponse().get("real_offset").asLong(); + } + return new CommentsResponse(comments, count, realOffset, profiles, groups); + } } diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java new file mode 100644 index 0000000..1cf58bf --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java @@ -0,0 +1,27 @@ +package org.springframework.social.vkontakte.api.impl.json; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.springframework.social.vkontakte.api.impl.json.deserializers.UnixTimeDeserializer; + +import java.util.Date; + +/** + * Mixin for {@link org.springframework.social.vkontakte.api.Comment} + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class CommentMixin { + @JsonProperty("from_id") + long fromId; + + @JsonProperty("date") + @JsonDeserialize(using = UnixTimeDeserializer.class) + Date date; + + @JsonProperty("reply_to_user") + long replyToUser; + + @JsonProperty("reply_to_comment") + long replyToComment; +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java new file mode 100644 index 0000000..4bc6046 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java @@ -0,0 +1,42 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.springframework.social.vkontakte.api.impl.json; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CountersMixin { + private int albums; + private int videos; + private int audios; + private int notes; + private int photos; + private int groups; + private int gifts; + private int friends; + @JsonProperty("online_friends") + private int onlineFriends; + @JsonProperty("mutual_friends") + private int mutualFriends; + @JsonProperty("user_photos") + private int userPhotos; + @JsonProperty("user_videos") + private int userVideos; + private int followers; + private int subscriptions; + private int pages; +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java index 5a89dca..319997f 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java @@ -50,6 +50,7 @@ public void setupModule(SetupContext context) { context.setMixInAnnotations(Post.Comments.class, PostCommentsMixin.class); context.setMixInAnnotations(Post.Geo.class, PostGeoMixin.class); context.setMixInAnnotations(Place.class, PostGeoPlaceMixin.class); + context.setMixInAnnotations(Comment.class, CommentMixin.class); context.setMixInAnnotations(Group.class, GroupMixin.class); @@ -71,6 +72,7 @@ public void setupModule(SetupContext context) { context.setMixInAnnotations(City.class, CityMixin.class); context.setMixInAnnotations(Country.class, CountryMixin.class); context.setMixInAnnotations(LastSeen.class, LastSeenMixin.class); + context.setMixInAnnotations(Counters.class, CountersMixin.class); context.setMixInAnnotations(Occupation.class, OccupationMixin.class); context.setMixInAnnotations(Personal.class, PersonalMixin.class); context.setMixInAnnotations(University.class, UniversityMixin.class); diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java index f3c9b36..5fd497c 100644 --- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.springframework.social.vkontakte.api.*; @@ -97,6 +96,7 @@ class VKontakteProfileMixin { private String facebookName; @JsonProperty("twitter") private String twitter; + private String instagram; @JsonProperty("site") private String site; @JsonProperty("status") @@ -155,6 +155,9 @@ class VKontakteProfileMixin { private VKontakteProfile relationPartner; @JsonProperty("last_seen") private LastSeen lastSeen; + @JsonProperty("counters") + private Counters counters; + static class VKGenderDeserializer extends JsonDeserializer { @Override diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java new file mode 100644 index 0000000..b30f3ca --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java @@ -0,0 +1,111 @@ +package org.springframework.social.vkontakte.api.impl.wall; + +import org.springframework.social.vkontakte.api.IWallOperations; +import org.springframework.social.vkontakte.api.vkenums.SortOrder; + +/** + * Model class representing query for the list of comments on a post on a user wall or community wall. + * + * @see IWallOperations#getComments(CommentsQuery) + * @see wall.getComments | Developers | VK + */ +public final class CommentsQuery { + public final WallOwner owner; + public final int postId; + public final boolean needLikes; + public final Integer startCommentId; + public final Integer offset; + public final Integer count; + public final SortOrder sort; + public final Integer previewLength; + public final boolean extended; + + public CommentsQuery(WallOwner owner, int postId, boolean needLikes, Integer startCommentId, Integer offset, Integer count, SortOrder sort, Integer previewLength, boolean extended) { + this.owner = owner; + this.postId = postId; + this.needLikes = needLikes; + this.startCommentId = startCommentId; + this.offset = offset; + this.count = count; + this.sort = sort; + this.previewLength = previewLength; + this.extended = extended; + } + + @Override + public String toString() { + return "CommentsQuery{" + + "owner='" + owner + '\'' + + ", postId=" + postId + + '}'; + } + + public static class Builder { + private WallOwner owner; + private Integer postId; + private boolean needLikes; + private Integer startCommentId; + private Integer offset; + private Integer count; + private SortOrder sort; + private Integer previewLength; + private boolean extended; + + /** + * @param owner {@link UserWall} or {@link UserWall} + * @param postId post ID. + */ + public Builder(WallOwner owner, int postId) { + this.owner = owner; + this.postId = postId; + } + + public Builder needLikes(boolean needLikes) { + this.needLikes = needLikes; + return this; + } + + public Builder startCommentId(int startCommentId) { + this.startCommentId = startCommentId; + return this; + } + + public Builder offset(int offset) { + this.offset = offset; + return this; + } + + /** + * @param count number of comments to return (maximum 100) + * @return {@link org.springframework.social.vkontakte.api.impl.wall.CommentsQuery.Builder} + */ + public Builder count(int count) { + this.count = count; + return this; + } + + public Builder sort(SortOrder sort) { + this.sort = sort; + return this; + } + + /** + * @param previewLength number of characters at which to truncate comments when previewed. + * If {@code null} or {@code 0} comments are not truncated. + * @return {@link org.springframework.social.vkontakte.api.impl.wall.CommentsQuery.Builder} + */ + public Builder previewLength(int previewLength) { + this.previewLength = previewLength; + return this; + } + + public Builder extended(boolean extended) { + this.extended = extended; + return this; + } + + public CommentsQuery build() { + return new CommentsQuery(owner, postId, needLikes, startCommentId, offset, count, sort, previewLength, extended); + } + } +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java new file mode 100644 index 0000000..ef20c18 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java @@ -0,0 +1,21 @@ +package org.springframework.social.vkontakte.api.impl.wall; + +/** + * Model class representing community wall owner + * + * @see WallOwner + * @see CommentsQuery#owner + */ +public final class CommunityWall extends WallOwner { + public CommunityWall(final long communityId) { + super(communityId); + } + + @Override + public String toString() { + return "CommunityWall{" + + "id='" + getId() + '\'' + + '}'; + } + +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java new file mode 100644 index 0000000..7511a71 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java @@ -0,0 +1,21 @@ +package org.springframework.social.vkontakte.api.impl.wall; + +/** + * Model class representing user wall owner + * + * @see WallOwner + * @see CommentsQuery#owner + */ +public final class UserWall extends WallOwner { + public UserWall(final long userId) { + super(userId); + } + + @Override + public String toString() { + return "UserWall{" + + "id='" + getId() + '\'' + + '}'; + } +} + diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java new file mode 100644 index 0000000..1753477 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java @@ -0,0 +1,20 @@ +package org.springframework.social.vkontakte.api.impl.wall; + +/** + * Model class representing an abstract wall's owner + * + * @see UserWall + * @see CommunityWall + * @see CommentsQuery#owner + */ +public abstract class WallOwner { + private final long id; + + protected WallOwner(final long ownerId) { + this.id = ownerId; + } + + public long getId() { + return id; + } +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java new file mode 100644 index 0000000..fad570d --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.springframework.social.vkontakte.api.vkenums; + +/** + * Defines sort order for friends.get operation + * API.version = 5.35 + * @author dIsoVi + */ +public enum FriendsOrder { + NONE, + hints, + random, + mobile, + name +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java new file mode 100644 index 0000000..041f1f9 --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.springframework.social.vkontakte.api.vkenums; + +/** + * Case for declension of user name and surname + * API.version = 5.35 + * @author dIsoVi + */ +public enum NameCase { + nom, // default + gen, + dat, + acc, + ins, + abl +} diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java new file mode 100644 index 0000000..1c2301a --- /dev/null +++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java @@ -0,0 +1,9 @@ +package org.springframework.social.vkontakte.api.vkenums; + +/** + * Defines sort order for wall.getComments operation + */ +public enum SortOrder { + asc, + desc +} diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java index 6b88af6..2c3bb7d 100644 --- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java @@ -19,6 +19,7 @@ import org.springframework.social.MissingAuthorizationException; import org.springframework.social.vkontakte.api.VKontakteErrorException; import org.springframework.social.vkontakte.api.VKontakteProfile; +import org.springframework.social.vkontakte.api.impl.json.VKArray; import java.text.ParseException; import java.util.List; @@ -41,11 +42,22 @@ public void get_currentUser() throws ParseException { .andExpect(method(GET)) .andRespond(withSuccess(jsonResource("list-of-friends-5_27"), APPLICATION_JSON)); - List friends = vkontakte.friendsOperations().get(); + VKArray friends = vkontakte.friendsOperations().get(); assertFriends(friends); } - @Test(expected = MissingAuthorizationException.class) + @Test + public void getFriendsWithoutFields() throws Exception { + mockServer.expect(requestTo("https://api.vk.com/method/friends.get?access_token=ACCESS_TOKEN&v=5.27")) + .andExpect(method(GET)) + .andRespond(withSuccess(jsonResource("friends-get-without-fields-5_35"), APPLICATION_JSON)); + VKArray friends = vkontakte.friendsOperations().get(""); + assertEquals(184760, friends.getItems().get(0).getId()); + assertEquals(3, friends.getItems().size()); + assertEquals(718, friends.getCount()); + } + + @Test(expected = MissingAuthorizationException.class) public void get_currentUser_unauthorized() { unauthorizedVKontakte.friendsOperations().get(); } @@ -56,7 +68,7 @@ public void get_byUserId() throws ParseException { .andExpect(method(GET)) .andRespond(withSuccess(jsonResource("list-of-friends-5_27"), APPLICATION_JSON)); - List friends = vkontakte.friendsOperations().get(1L); + VKArray friends = vkontakte.friendsOperations().get(1L); assertFriends(friends); } @@ -132,7 +144,9 @@ public void getOnlineAllParametersPresent() { vkontakte.friendsOperations().getOnline(123L, true, 5, 6); } - private void assertFriends(List profiles) throws ParseException { + private void assertFriends(VKArray profilesArray) throws ParseException { + List profiles = profilesArray.getItems(); + assertEquals(705, profilesArray.getCount()); assertEquals(5, profiles.size()); assertEquals(15439101, profiles.get(0).getId()); } diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java index d30a91c..9805c46 100644 --- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java @@ -19,13 +19,13 @@ import org.springframework.social.MissingAuthorizationException; import org.springframework.social.vkontakte.api.VKontakteErrorException; import org.springframework.social.vkontakte.api.VKontakteProfile; +import org.springframework.social.vkontakte.api.vkenums.NameCase; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; @@ -40,23 +40,26 @@ public class UsersTemplateTest extends AbstractVKontakteApiTest { @Test public void getUser_currentUser() { mockServer - .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=sex%2C+bdate%2C+city%2C+country%2C+photo_50%2C+photo_100%2C+photo_200_orig%2C+photo_200%2C+photo_400_orig%2C+photo_max%2C+photo_max_orig%2C+photo_id%2C+online%2C+online_mobile%2C+domain%2C+has_mobile%2C+contacts%2C+connections%2C+site%2C+education%2C+universities%2C+schools%2C+can_post%2C+can_see_all_posts%2C+can_see_audio%2C+can_write_private_message%2C+status%2C+last_seen%2C+common_count%2C+relation%2C+relatives%2C+counters%2C+screen_name%2C+maiden_name%2C+timezone%2C+occupation%2Cactivities%2C+interests%2C+music%2C+movies%2C+tv%2C+books%2C+games%2C+about%2C+quotes%2C+personal%2C+friends_status")) - .andExpect(method(GET)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON)); + .expect(requestTo("https://api.vk.com/method/users.get")) + .andExpect(method(POST)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON)); VKontakteProfile profile = vkontakte.usersOperations().getUser("sex, bdate, city, country, photo_50, photo_100, photo_200_orig, photo_200, photo_400_orig, photo_max, photo_max_orig, photo_id, online, online_mobile, domain, has_mobile, contacts, connections, site, education, universities, schools, can_post, can_see_all_posts, can_see_audio, can_write_private_message, status, last_seen, common_count, relation, relatives, counters, screen_name, maiden_name, timezone, occupation,activities, interests, music, movies, tv, books, games, about, quotes, personal, friends_status"); assertEquals(1, profile.getId()); assertEquals("Павел", profile.getFirstName()); assertEquals("Дуров", profile.getLastName()); + assertEquals(705, profile.getCounters().getFriends()); + assertEquals(12, profile.getCounters().getUserPhotos()); + assertEquals("durov", profile.getInstagram()); } @Test public void getUsers_currentUser() { mockServer - .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name&user_ids=1%2C2183%2C77478")) - .andExpect(method(GET)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON)); - Long[] userIds = {1L, 2183L, 77478L}; - List profiles = vkontakte.usersOperations().getUsers(Arrays.asList(userIds)); + .expect(requestTo("https://api.vk.com/method/users.get")) + .andExpect(method(POST)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON)); + String[] userIds = {"durov", "2183", "77478"}; + List profiles = vkontakte.usersOperations().getUsers(Arrays.asList(userIds), null, NameCase.abl); assertProfiles(profiles); } @@ -68,15 +71,15 @@ public void getUser_unauthorized() { @Test(expected = MissingAuthorizationException.class) public void getUsers_unauthorized() { - Long[] userIds = {1L, 2L}; + String[] userIds = {"1", "2"}; unauthorizedVKontakte.usersOperations().getUsers(Arrays.asList(userIds)); } @Test(expected = VKontakteErrorException.class) public void getUser_expiredToken() { mockServer - .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name")) - .andExpect(method(GET)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON)); + .expect(requestTo("https://api.vk.com/method/users.get")) + .andExpect(method(POST)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON)); vkontakte.usersOperations().getUser(); } @@ -84,9 +87,9 @@ public void getUser_expiredToken() { @Test(expected = VKontakteErrorException.class) public void getUsers_expiredToken() { mockServer - .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name&user_ids=1%2C2")) - .andExpect(method(GET)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON)); - Long[] userIds = {1L, 2L}; + .expect(requestTo("https://api.vk.com/method/users.get")) + .andExpect(method(POST)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON)); + String[] userIds = {"1", "2"}; vkontakte.usersOperations().getUsers(Arrays.asList(userIds)); } diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java index 4dae470..7acbbb2 100644 --- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java @@ -16,10 +16,12 @@ package org.springframework.social.vkontakte.api.impl; import org.junit.Test; +import org.springframework.social.vkontakte.api.VKGenericResponse; import org.springframework.social.vkontakte.api.VKObject; import static org.junit.Assert.assertEquals; import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; @@ -32,7 +34,7 @@ public class UtilsTemplateTest extends AbstractVKontakteApiTest { @Test public void resolveScreenName() { - mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=&v=5.27&screen_name=durov")) + mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=ACCESS_TOKEN&v=5.27&screen_name=durov")) .andExpect(method(GET)) .andRespond(withSuccess(jsonResource("utils-resolve-screen-name-5.27"), APPLICATION_JSON)); VKObject vkObject = vkontakte.utilsOperations().resolveScreenName("durov"); @@ -42,10 +44,38 @@ public void resolveScreenName() { @Test public void resolveScreenNameEmpty() { - mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=&v=5.27&screen_name=durov")) + mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=ACCESS_TOKEN&v=5.27&screen_name=durov")) .andExpect(method(GET)) .andRespond(withSuccess(jsonResource("utils-resolve-screen-name-empty-5.27"), APPLICATION_JSON)); VKObject vkObject = vkontakte.utilsOperations().resolveScreenName("durov"); assertEquals(null, vkObject); } + + @Test + public void testExecute() throws Exception { + mockServer.expect(requestTo("https://api.vk.com/method/execute")) + .andExpect(method(POST)) + .andRespond(withSuccess(jsonResource("utils-execute-response-5_35"), APPLICATION_JSON)); + String code = "var posts = API.wall.get({\"count\": 1});\n" + + "\n" + + "if (posts.count<0) {\n" + + " return {\"post\": null, \"copy_owner\": null};\n" + + "} else {\n" + + " var post = posts.items[0];\n" + + " var copy_owner=null;\n" + + " if (post.copy_history[0]){\n" + + " if (post.copy_history[0].owner_id > 0) {\n" + + " copy_owner = API.users.get({\"user_id\": post.copy_history[0].owner_id})[0];\n" + + " } else\n" + + " if (post.copy_history[0].owner_id < 0) {\n" + + " copy_owner = API.groups.getById({\"group_ids\": -post.copy_history[0].owner_id})[0];\n" + + " }\n" + + " return {\"post\": post, \"copy_owner\": copy_owner};\n" + + " } else {\n" + + " return {\"post\": post, \"copy_owner\": null};\n" + + " }\n" + + "}"; + VKGenericResponse response = vkontakte.utilsOperations().execute(code); + assertEquals(1, response.getResponse().get("post").get("copy_history").size()); + } } diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java index 1892a50..becde61 100644 --- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java @@ -16,15 +16,26 @@ package org.springframework.social.vkontakte.api.impl; import org.junit.Test; +import org.springframework.social.vkontakte.api.Comment; +import org.springframework.social.vkontakte.api.CommentsResponse; import org.springframework.social.vkontakte.api.Post; -import org.springframework.social.vkontakte.api.attachment.*; +import org.springframework.social.vkontakte.api.VKontakteProfile; +import org.springframework.social.vkontakte.api.attachment.Attachment; +import org.springframework.social.vkontakte.api.attachment.AttachmentType; +import org.springframework.social.vkontakte.api.attachment.PhotosListAttachment; +import org.springframework.social.vkontakte.api.attachment.StickerAttachment; +import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery; +import org.springframework.social.vkontakte.api.impl.wall.CommunityWall; +import org.springframework.social.vkontakte.api.impl.wall.UserWall; +import org.springframework.social.vkontakte.api.vkenums.SortOrder; import java.util.List; + import static org.junit.Assert.assertEquals; import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; /** @@ -43,7 +54,63 @@ public void getPosts() { assertEquals(AttachmentType.PHOTOS_LIST, photosListAttachment.getType()); assertEquals(306810815, ((PhotosListAttachment)photosListAttachment).getPhotosList().get(0).getPhotoId()); assertEquals(45555, posts.get(1).getId()); + assertEquals(22694, posts.get(1).getLikes().getCount()); + assertEquals(false, posts.get(1).getLikes().isUserLikes()); assertEquals(2, posts.get(1).getAttachments().size()); assertEquals(3, ((StickerAttachment)posts.get(22).getCopyHistory().get(0).getAttachments().get(0)).getSticker().getProductId()); } + + @Test + public void getCommunityWallComments() { + mockServer + .expect(requestTo("https://api.vk.com/method/wall.getComments")) + .andExpect(method(POST)) + .andExpect(content().string("owner_id=-85635407&post_id=3199&preview_length=0&access_token=ACCESS_TOKEN&v=5.33")) + .andRespond(withSuccess(jsonResource("wall-getComments-response-5_33"), APPLICATION_JSON)); + CommentsQuery request = new CommentsQuery.Builder(new CommunityWall(85635407), 3199).build(); + + CommentsResponse response = vkontakte.wallOperations().getComments(request); + + assertEquals(16, response.getCount()); + } + + @Test + public void getUserWallComments() { + mockServer + .expect(requestTo("https://api.vk.com/method/wall.getComments")) + .andExpect(method(POST)) + .andExpect(content().string("owner_id=85635407&post_id=3199&need_likes=1&start_comment_id=3204&offset=2&count=3&sort=desc&preview_length=9999&extended=1&access_token=ACCESS_TOKEN&v=5.33")) + .andRespond(withSuccess(jsonResource("wall-getComments-response-5_33"), APPLICATION_JSON)); + CommentsQuery request = new CommentsQuery(new UserWall(85635407), 3199, true, 3204, 2, 3, SortOrder.desc, 9999, true); + + CommentsResponse response = vkontakte.wallOperations().getComments(request); + + assertEquals(16, response.getCount()); + assertEquals(10, response.getRealOffset()); + + assertEquals(6, response.getComments().size()); + assertEquals(4, response.getProfiles().size()); + + assertComment(response.getComments().get(0)); + assertProfile(response.getProfiles().get(0)); + } + + private void assertComment(Comment comment) { + assertEquals(3205, comment.getId()); + assertEquals(1375980597000L, comment.getDate().getTime()); + assertEquals(85635407, comment.getFromId()); + assertEquals("[id3197366|Андрей], поправил", comment.getText()); + assertEquals(3197366, comment.getReplyToUser()); + assertEquals(3200, comment.getReplyToComment()); + assertEquals(666, comment.getLikes().getCount()); + assertEquals(true, comment.getLikes().isUserLikes()); + assertEquals(2, comment.getAttachments().size()); + } + + private void assertProfile(VKontakteProfile profile) { + assertEquals(3197366, profile.getId()); + assertEquals("suppo", profile.getScreenName()); + assertEquals("M", profile.getGender()); + assertEquals(true, profile.isOnline()); + } } diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json new file mode 100644 index 0000000..73a4296 --- /dev/null +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json @@ -0,0 +1,10 @@ +{ + "response": { + "count": 718, + "items": [ + 184760, + 3271875, + 680751 + ] + } +} \ No newline at end of file diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json index 3e8a12b..e06f53e 100644 --- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json @@ -45,9 +45,13 @@ "audios": 0, "notes": 6, "photos": 188, + "groups": 123, + "gifts": 11, "friends": 705, "online_friends": 131, "mutual_friends": 1, + "user_photos": 12, + "user_videos": 1, "followers": 6155681, "subscriptions": 0, "pages": 37 diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json new file mode 100644 index 0000000..fec87a5 --- /dev/null +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json @@ -0,0 +1,240 @@ +{ + "response": { + "post": { + "id": 175, + "from_id": 16051904, + "owner_id": 16051904, + "date": 1438767744, + "post_type": "post", + "text": "", + "copy_history": [ + { + "id": 23577, + "owner_id": -60114472, + "from_id": -60114472, + "date": 1438743721, + "post_type": "post", + "text": "René Magritte", + "attachments": [ + { + "type": "photo", + "photo": { + "id": 375542583, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a54/j29vXksmjtw.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a55/_inafzIXl6o.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a56/JQ58ZpF7T98.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a57/cEhY5JqPABw.jpg", + "width": 640, + "height": 532, + "text": "", + "date": 1438743720, + "access_key": "3d8a69e9341e4e44ec" + } + }, + { + "type": "photo", + "photo": { + "id": 375542584, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a5c/LRUr-ydV7ls.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a5d/ciOtHI88vP0.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a5e/rftPC6GvRyQ.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a5f/zCtqiD0EF04.jpg", + "width": 640, + "height": 799, + "text": "", + "date": 1438743720, + "access_key": "e48368517e6a8e40b4" + } + }, + { + "type": "photo", + "photo": { + "id": 375542585, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a64/_bJgQpcgrCs.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a65/3ebcbffCBFs.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a66/9pmrLtry6aE.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a67/-xMdKLMKxM8.jpg", + "width": 500, + "height": 700, + "text": "", + "date": 1438743720, + "access_key": "dfb59f861e40c302a0" + } + }, + { + "type": "photo", + "photo": { + "id": 375542586, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a6c/Eb1Pw97d8eA.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a6d/RIqRAdkMqaQ.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a6e/BsfgVP9YbBg.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a6f/n3jpPk3QG-4.jpg", + "width": 640, + "height": 351, + "text": "", + "date": 1438743720, + "access_key": "9b2e6deb9886ce6b61" + } + }, + { + "type": "photo", + "photo": { + "id": 375542587, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a74/b_ivrxTPuCk.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a75/2mC0wLr14rY.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a76/IqiEm_LOvEA.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a77/kP1O2I4kRi0.jpg", + "width": 640, + "height": 480, + "text": "", + "date": 1438743720, + "access_key": "cf4c1d0dc3bc4c1e07" + } + }, + { + "type": "photo", + "photo": { + "id": 375542588, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a7c/oR5QFjFZ6AM.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a7d/1clxLbH68LM.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a7e/UVzIS9L9No8.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a7f/lnDK5g2U8Ww.jpg", + "photo_1280": "https://pp.vk.me/c543101/v543101677/26a80/nf1UMlRiCy0.jpg", + "width": 640, + "height": 843, + "text": "", + "date": 1438743720, + "access_key": "22cace3b223e511a59" + } + }, + { + "type": "photo", + "photo": { + "id": 375542589, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a85/ImP5oYSw_rg.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a86/I3D8WGB6qzI.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a87/PylA1209YpE.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a88/_JW0W06DwjU.jpg", + "photo_1280": "https://pp.vk.me/c543101/v543101677/26a89/0h_oeDL1mQo.jpg", + "width": 640, + "height": 869, + "text": "", + "date": 1438743720, + "access_key": "a1161d3406f887a021" + } + }, + { + "type": "photo", + "photo": { + "id": 375542590, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a8e/reBCRflPqUc.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a8f/pPfh5BxfoQU.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a90/3MBQfGrEhwY.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a91/zdpgvjpLA7U.jpg", + "width": 640, + "height": 526, + "text": "", + "date": 1438743720, + "access_key": "81e00501271e98c8af" + } + }, + { + "type": "photo", + "photo": { + "id": 375542591, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a96/qhlqwJRED20.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a97/c5TlU2G4cws.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26a98/cvIkwyIEBME.jpg", + "photo_807": "https://pp.vk.me/c543101/v543101677/26a99/XyNPm9aljK0.jpg", + "width": 640, + "height": 798, + "text": "", + "date": 1438743720, + "access_key": "f5b0c2cdec3c770910" + } + }, + { + "type": "photo", + "photo": { + "id": 375542592, + "album_id": -7, + "owner_id": -60114472, + "user_id": 100, + "photo_75": "https://pp.vk.me/c543101/v543101677/26a9e/5Y8x_UVykgA.jpg", + "photo_130": "https://pp.vk.me/c543101/v543101677/26a9f/piwJlIg7jMY.jpg", + "photo_604": "https://pp.vk.me/c543101/v543101677/26aa0/Bbmw97OK6ag.jpg", + "width": 398, + "height": 600, + "text": "", + "date": 1438743720, + "access_key": "fe711c8eb518cc4499" + } + } + ], + "post_source": { + "type": "api" + } + } + ], + "can_edit": 1, + "can_delete": 1, + "can_pin": 1, + "post_source": { + "type": "vk" + }, + "comments": { + "count": 0, + "can_post": 1 + }, + "likes": { + "count": 0, + "user_likes": 0, + "can_like": 1, + "can_publish": 0 + }, + "reposts": { + "count": 0, + "user_reposted": 0 + } + }, + "copy_owner": { + "id": 60114472, + "name": "Albertina", + "screen_name": "al_bertina", + "is_closed": 0, + "type": "page", + "is_admin": 0, + "is_member": 1, + "photo_50": "https://pp.vk.me/c312927/v312927711/4e8d/Gd1mm_PHYaI.jpg", + "photo_100": "https://pp.vk.me/c312927/v312927711/4e8c/mEkXL9VFsEA.jpg", + "photo_200": "https://pp.vk.me/c312927/v312927711/4e8b/8zPo3HESmow.jpg" + } + } +} \ No newline at end of file diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json new file mode 100644 index 0000000..ddf6bcc --- /dev/null +++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json @@ -0,0 +1,153 @@ +{ + "response": { + "count": 16, + "real_offset": 10, + "items": [ + { + "id": 3205, + "from_id": 85635407, + "date": 1375980597, + "text": "[id3197366|Андрей], поправил", + "likes": { + "count": 666, + "user_likes": 1, + "can_like": 1 + }, + "reply_to_user": 3197366, + "reply_to_comment": 3200, + "attachments": [ + { + "type": "photo", + "photo": { + "id": 308701914, + "album_id": -5, + "owner_id": 85635407, + "photo_75": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef0\/q4rguINFKc0.jpg", + "photo_130": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef1\/sjEQyroiYac.jpg", + "photo_604": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef2\/24e6zf6JT8E.jpg", + "width": 591, + "height": 118, + "text": "Original: http:\/\/s2.1pic.org\/files\/2013\/08\/08\/e89e7b5e6b7cfe6d8aa5.jpg", + "date": 1375979968, + "access_key": "f5083a22fe3d0b6f2f" + } + }, + { + "type": "audio", + "audio": { + "id": 283017386, + "owner_id": 85635407, + "artist": "San Cisco", + "title": "Beach", + "duration": 227, + "url": "http://cs6191.vk.me/u156280183/audios/7453f3072442.mp3?extra=DtlNCRK0Wf-9AiLZiBKfB7rTCZjeeF2C7ri88acWH0rk-meDbDZMbGmTBaygzzeklPz7qxOlpASUpLjeJmNJCi0aVxUkz9w", + "lyrics_id": 125602217, + "album_id": 2, + "genre_id": 9 + } + } + ] + }, + { + "id": 3204, + "from_id": 85635407, + "date": 1375980529, + "text": "[id19498153|Макс], не могу =(", + "likes": { + "count": 0, + "user_likes": 0, + "can_like": 1 + }, + "reply_to_user": 19498153, + "reply_to_comment": 3203 + }, + { + "id": 3203, + "from_id": 19498153, + "date": 1375980513, + "text": "Лимит увеличь, молю!", + "likes": { + "count": 2, + "user_likes": 0, + "can_like": 1 + } + }, + { + "id": 3202, + "from_id": 40001922, + "date": 1375980076, + "text": "Наконец-то! Спасибо.", + "likes": { + "count": 2, + "user_likes": 0, + "can_like": 1 + } + }, + { + "id": 3201, + "from_id": 3197366, + "date": 1375979984, + "text": "И, я думаю, если я не админ, то мне не нужны фотографии сообщества, не?", + "likes": { + "count": 0, + "user_likes": 0, + "can_like": 1 + } + }, + { + "id": 3200, + "from_id": 3197366, + "date": 1375979966, + "text": "Однако баг:", + "likes": { + "count": 1, + "user_likes": 0, + "can_like": 1 + } + } + ], + "profiles": [ + { + "id": 3197366, + "first_name": "Андрей", + "last_name": "Андреев", + "sex": 2, + "screen_name": "suppo", + "photo_50": "https:\/\/pp.vk.me\/c629516\/v629516366\/2509e\/j1RWzBSsx34.jpg", + "photo_100": "https:\/\/pp.vk.me\/c629516\/v629516366\/2509d\/Y_WW-9c59KA.jpg", + "online": 1 + }, + { + "id": 19498153, + "first_name": "Максим", + "last_name": "Долженко", + "sex": 2, + "screen_name": "md", + "photo_50": "https:\/\/pp.vk.me\/c624816\/v624816153\/3866c\/bkxkxJ0xn5I.jpg", + "photo_100": "https:\/\/pp.vk.me\/c624816\/v624816153\/3866b\/fyT0u8Fr0Jo.jpg", + "online": 1 + }, + { + "id": 40001922, + "first_name": "Sergey", + "last_name": "Golitsyn", + "sex": 2, + "screen_name": "golitsyn", + "photo_50": "https:\/\/pp.vk.me\/c311621\/v311621922\/9ac0\/qtqzaeBwJkA.jpg", + "photo_100": "https:\/\/pp.vk.me\/c311621\/v311621922\/9abf\/0oziI23A7gI.jpg", + "online": 0 + }, + { + "id": 85635407, + "first_name": "Олег", + "last_name": "Илларионов", + "sex": 2, + "screen_name": "derp", + "photo_50": "https:\/\/pp.vk.me\/c620831\/v620831407\/1638f\/6qaLGdESeIw.jpg", + "photo_100": "https:\/\/pp.vk.me\/c620831\/v620831407\/1638e\/wKAZXphhssY.jpg", + "online": 0 + } + ], + "groups": [] + } +} \ No newline at end of file