/* * Copyright (C) 2013 Jonathan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tumblrviewer; import com.tumblr.jumblr.*; import com.tumblr.jumblr.exceptions.JumblrException; import com.tumblr.jumblr.types.*; import java.net.MalformedURLException; import java.net.URL; import java.util.*; import javax.swing.ImageIcon; import javax.swing.JOptionPane; /** * * @author jonathan */ public class TumblrBackend { private static final int POSTS_LOADED_PER_UPDATE = 20; private static final boolean FULLSIZE_PHOTOS = false; static final int PHOTO_PREFERRED_SIZE = 500; // (100/250/400/500) private static final int DEFAULT_AVATAR_SIZE = 16; final DisplayModes currentDisplayMode; /* End of constants*/ private final MainViewGUI gui; private int currentUpdateIndex = 0; private JumblrClient client; private User user; final String guiTitle; private final String currentlyViewingBlog; static private HashSet<String> allUserFollowing; static private HashSet<String> allUserFollowers; public enum DisplayModes { POSTS, LIKES, DASHBOARD }; public String getCurrentViewingBlog() { return currentlyViewingBlog; } public DisplayModes getCurrentDisplayMode() { return currentDisplayMode; } public TumblrBackend(MainViewGUI gui, DisplayModes currentDisplayMode, String currentlyViewingBlog) { this.gui = gui; this.currentDisplayMode = currentDisplayMode; try { client = new JumblrClient(java.util.ResourceBundle.getBundle("Keys").getString("consumer_key"), java.util.ResourceBundle.getBundle("Keys").getString("consumer_secret")); client.setToken(java.util.ResourceBundle.getBundle("Keys").getString("oauth_token"), java.util.ResourceBundle.getBundle("Keys").getString("oauth_token_secret")); user = client.user(); } catch (Exception e) { JOptionPane.showMessageDialog(gui.getJFrame(), e, "Connection Exception", JOptionPane.ERROR_MESSAGE); System.exit(1); } if (currentlyViewingBlog == null) { this.currentlyViewingBlog = user.getName(); } else { this.currentlyViewingBlog = currentlyViewingBlog; } guiTitle = java.util.ResourceBundle.getBundle("en_gb").getString(currentDisplayMode.name() + " FOR ") + this.currentlyViewingBlog; gui.getJFrame().setTitle(guiTitle); } public void reblogThis(Post post) { try { //client.postReblog(user.getName(), post.getId(), post.getReblogKey()); post.reblog(user.getName()); } catch (Exception e) { } } public void tumblrLoadMore() { tumblrUpdate(currentUpdateIndex); currentUpdateIndex++; } private void tumblrUpdate(int offsetIndex) { Map<String, Object> params = new HashMap<>(); /*if (currentDisplayMode == DisplayModes.DASHBOARD && lastPostId != null) { params.put("since_id", lastPostId); } else {*/ params.put("offset", offsetIndex * POSTS_LOADED_PER_UPDATE); /*}*/ params.put("limit", POSTS_LOADED_PER_UPDATE); params.put("reblog_info", true); List<Post> posts = null; try { switch (currentDisplayMode) { case POSTS: posts = client.blogPosts(currentlyViewingBlog, params); break; case LIKES: if (isCurrentUsersBlog()) { posts = client.userLikes(params); //Use different method because current user might have set likes to private } else { posts = client.blogLikes(currentlyViewingBlog, params); } break; case DASHBOARD: posts = client.userDashboard(params); break; } } catch (Exception e) { System.err.println("Couldn't retrieve ANY posts!"); //NOI18N return; } for (Post post : posts) { try { PhotoPost photoPost = PhotoPost.class.cast(post); List<Photo> photosInPost = photoPost.getPhotos(); for (Photo photo : photosInPost) { List<PhotoSize> photoSizes = photo.getSizes(); for (PhotoSize photoSize : photoSizes) { if (!FULLSIZE_PHOTOS) //The first one is the fullsize photo so this won't run if FULLSIZE_PHOTOS is set to true { if (!photoSize.getUrl().contains("_" + PHOTO_PREFERRED_SIZE + ".")) { continue; //Wrong size so contine } } gui.addImage(photoSize.getUrl(), photoPost, photosInPost.indexOf(photo)); break; //Only add one of the image sizes - we have now done this } } } catch (Exception e) { //e.printStackTrace(); //Fail silently so that non-photo posts simply get ignored when the cast fails } } } public boolean isCurrentlyLiked(Post post) { String blogName = post.getBlogName(); Long postId = post.getId(); return client.blogPost(blogName, postId).isLiked(); } public int getCurrentNoteCount(Post post) { String blogName = post.getBlogName(); Long postId = post.getId(); Map<String, Object> params = new HashMap<>(); params.put("id", postId); params.put("reblog_info", true); params.put("notes_info", true); java.util.List<Post> posts = client.blogPosts(blogName, params); PhotoPost detailedPhotoPost = PhotoPost.class.cast(posts.get(0)); return detailedPhotoPost.getNoteCount(); } public Note[] getCurrentNotes(Post post) { String blogName = post.getBlogName(); Long postId = post.getId(); Map<String, Object> params = new HashMap<>(); params.put("id", postId); params.put("reblog_info", true); params.put("notes_info", true); java.util.List<Post> posts = client.blogPosts(blogName, params); PhotoPost detailedPhotoPost = PhotoPost.class.cast(posts.get(0)); return detailedPhotoPost.getNotes(); } public ImageIcon getAvatar(String user) { return getAvatar(user, DEFAULT_AVATAR_SIZE); } public ImageIcon getAvatar(String user, int avatarSize) { String avatarUrl = "http://api.tumblr.com/v2" + JumblrClient.blogPath(user, "/avatar/" + avatarSize); try { URL url = new URL(avatarUrl); return new ImageIcon(url); } catch (MalformedURLException e) { return null; } } public boolean canViewLikes() { if (isCurrentUsersBlog() && !client.userLikes().isEmpty()) { return true; } try { if (!client.blogInfo(currentlyViewingBlog).likedPosts().isEmpty()) { return true; } } catch (JumblrException e) { return false; } return false; } public boolean isCurrentUsersBlog() { return client.user().getName().equals(currentlyViewingBlog); } public String getCurrentUsersName() { return client.user().getName(); } public synchronized boolean isFollowing(String user) { return allUserFollowing.contains(user); } public synchronized AbstractCollection<String> getAllUserFollowing() { if (allUserFollowing == null) { allUserFollowing = getAllUserFollowingCollection(); } return allUserFollowing; } public synchronized AbstractCollection<String> getAllUserFollowers() { if (allUserFollowers == null) { allUserFollowers = getAllUserFollowersCollection(); } return allUserFollowers; } private synchronized HashSet<String> getAllUserFollowingCollection() { HashSet<String> followingList = new HashSet<>(); final int recordsLoadedPerPage = 20; int totalCount = user.getFollowingCount(); for (int i = 0; i < (totalCount / recordsLoadedPerPage) + 1; i++) { Map<String, Object> params = new HashMap<>(); params.put("offset", (i * recordsLoadedPerPage)); params.put("limit", recordsLoadedPerPage); List<Blog> usersFollowing = client.userFollowing(params); for (Blog userFollowing : usersFollowing) { followingList.add(userFollowing.getName()); } } return followingList; } private HashSet<String> getAllUserFollowersCollection() { Blog blog = user.getBlogs().get(0); //TODO: Account for multiple blogs HashSet<String> followersList = new HashSet<>(); final int recordsLoadedPerPage = 20; int totalCount = blog.getFollowersCount(); for (int i = 0; i < (totalCount / recordsLoadedPerPage) + 1; i++) { Map<String, Object> params = new HashMap<>(); params.put("offset", (i * recordsLoadedPerPage)); params.put("limit", recordsLoadedPerPage); List<User> usersFollowers = blog.followers(params); for (User userFollower : usersFollowers) { followersList.add(userFollower.getName()); } } return followersList; } public void followBlog(String blog) { client.follow(blog); allUserFollowing.add(blog); //Update our internal list } public void unfollowBlog(String blog) { client.unfollow(blog); allUserFollowing.remove(blog); //Update our internal list } public boolean blogExists(String blogName) { try { client.blogPosts(blogName); } catch (Exception e) { return false; } return true; } }