public static void showAuthErrorView(Activity activity, int titleResId, int messageResId) {
    final String ALERT_TAG = "alert_ask_credentials";
    if (activity.isFinishing()) {
      return;
    }

    // WP.com errors will show the sign in activity
    if (WordPress.getCurrentBlog() == null
        || (WordPress.getCurrentBlog() != null && WordPress.getCurrentBlog().isDotcomFlag())) {
      Intent signInIntent = new Intent(activity, SignInActivity.class);
      signInIntent.putExtra(SignInActivity.ARG_IS_AUTH_ERROR, true);
      signInIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
      activity.startActivityForResult(signInIntent, SignInActivity.REQUEST_CODE);
      return;
    }

    // abort if the dialog is already visible
    if (activity.getFragmentManager().findFragmentByTag(ALERT_TAG) != null) {
      return;
    }

    FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
    AuthErrorDialogFragment authAlert = new AuthErrorDialogFragment();
    authAlert.setWPComTitleMessage(titleResId, messageResId);
    ft.add(authAlert, ALERT_TAG);
    ft.commitAllowingStateLoss();
  }
  /*
   * converts a date to a relative time span ("8h", "3d", etc.) - similar to
   * DateUtils.getRelativeTimeSpanString but returns shorter result
   */
  public static String javaDateToTimeSpan(final Date date) {
    if (date == null) return "";

    long passedTime = date.getTime();
    long currentTime = System.currentTimeMillis();

    // return "now" if less than a minute has elapsed
    long secondsSince = (currentTime - passedTime) / 1000;
    if (secondsSince < 60) return WordPress.getContext().getString(R.string.reader_timespan_now);

    // less than an hour (ex: 12m)
    long minutesSince = secondsSince / 60;
    if (minutesSince < 60) return Long.toString(minutesSince) + "m";

    // less than a day (ex: 17h)
    long hoursSince = minutesSince / 60;
    if (hoursSince < 24) return Long.toString(hoursSince) + "h";

    // less than a week (ex: 5d)
    long daysSince = hoursSince / 24;
    if (daysSince < 7) return Long.toString(daysSince) + "d";

    // less than a year old, so return day/month without year (ex: Jan 30)
    if (daysSince < 365)
      return DateUtils.formatDateTime(
          WordPress.getContext(),
          passedTime,
          DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL);

    // date is older, so include year (ex: Jan 30, 2013)
    return DateUtils.formatDateTime(
        WordPress.getContext(), passedTime, DateUtils.FORMAT_ABBREV_ALL);
  }
  private void refreshSummary() {
    if (WordPress.getCurrentBlog() == null) return;

    String blogId = WordPress.getCurrentBlog().getDotComBlogId();
    if (TextUtils.isEmpty(blogId)) blogId = "0";

    final String statsBlogId = blogId;
    new AsyncTask<Void, Void, StatsSummary>() {

      @Override
      protected StatsSummary doInBackground(Void... params) {
        return StatUtils.getSummary(statsBlogId);
      }

      protected void onPostExecute(final StatsSummary result) {
        if (getActivity() == null) return;
        getActivity()
            .runOnUiThread(
                new Runnable() {

                  @Override
                  public void run() {
                    refreshViews(result);
                  }
                });
      };
    }.execute();
  }
 private FeatureSet synchronousGetFeatureSet() {
   if (WordPress.getCurrentBlog() == null || !WordPress.getCurrentBlog().isDotcomFlag())
     return null;
   ApiHelper.GetFeatures task = new ApiHelper.GetFeatures();
   List<Object> apiArgs = new ArrayList<Object>();
   apiArgs.add(WordPress.getCurrentBlog());
   mFeatureSet = task.doSynchronously(apiArgs);
   return mFeatureSet;
 }
 private boolean areThemesAccessible() {
   // themes are only accessible to admin wordpress.com users
   if (WordPress.getCurrentBlog() != null && !WordPress.getCurrentBlog().isDotcomFlag()) {
     Intent intent = new Intent(ThemeBrowserActivity.this, PostsActivity.class);
     intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
     startActivityWithDelay(intent);
     return false;
   }
   return true;
 }
  /*
   * request info about a specific blog
   */
  public static void updateBlogInfo(
      long blogId, final String blogUrl, final UpdateBlogInfoListener infoListener) {
    // must pass either a valid id or url
    final boolean hasBlogId = (blogId != 0);
    final boolean hasBlogUrl = !TextUtils.isEmpty(blogUrl);
    if (!hasBlogId && !hasBlogUrl) {
      AppLog.w(T.READER, "cannot get blog info without either id or url");
      if (infoListener != null) {
        infoListener.onResult(null);
      }
      return;
    }

    RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            handleUpdateBlogInfoResponse(jsonObject, infoListener);
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            // authentication error may indicate that API access has been disabled for this blog
            int statusCode = VolleyUtils.statusCodeFromVolleyError(volleyError);
            boolean isAuthErr = (statusCode == HttpStatus.SC_FORBIDDEN);
            // if we failed to get the blog info using the id and this isn't an authentication
            // error, try again using just the domain
            if (!isAuthErr && hasBlogId && hasBlogUrl) {
              AppLog.w(T.READER, "failed to get blog info by id, retrying with url");
              updateBlogInfo(0, blogUrl, infoListener);
            } else {
              AppLog.e(T.READER, volleyError);
              if (infoListener != null) {
                infoListener.onResult(null);
              }
            }
          }
        };

    if (hasBlogId) {
      WordPress.getRestClientUtilsV1_1().get("read/sites/" + blogId, listener, errorListener);
    } else {
      WordPress.getRestClientUtilsV1_1()
          .get(
              "read/sites/" + UrlUtils.urlEncode(UrlUtils.getHost(blogUrl)),
              listener,
              errorListener);
    }
  }
  /** similar to updatePost, but used when post doesn't already exist in local db */
  public static void requestPost(
      final long blogId, final long postId, final ActionListener actionListener) {
    String path = "read/sites/" + blogId + "/posts/" + postId + "/?meta=site,likes";

    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            ReaderPost post = ReaderPost.fromJson(jsonObject);
            ReaderPostTable.addOrUpdatePost(post);
            handlePostLikes(post, jsonObject);
            if (actionListener != null) {
              actionListener.onActionResult(true);
            }
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            AppLog.e(T.READER, volleyError);
            if (actionListener != null) {
              actionListener.onActionResult(false);
            }
          }
        };
    AppLog.d(T.READER, "requesting post");
    WordPress.getRestClientUtilsV1_2().get(path, null, null, listener, errorListener);
  }
 public static void updateFeedInfo(
     long feedId, String feedUrl, final UpdateBlogInfoListener infoListener) {
   RestRequest.Listener listener =
       new RestRequest.Listener() {
         @Override
         public void onResponse(JSONObject jsonObject) {
           handleUpdateBlogInfoResponse(jsonObject, infoListener);
         }
       };
   RestRequest.ErrorListener errorListener =
       new RestRequest.ErrorListener() {
         @Override
         public void onErrorResponse(VolleyError volleyError) {
           AppLog.e(T.READER, volleyError);
           if (infoListener != null) {
             infoListener.onResult(null);
           }
         }
       };
   String path;
   if (feedId != 0) {
     path = "read/feed/" + feedId;
   } else {
     path = "read/feed/" + UrlUtils.urlEncode(feedUrl);
   }
   WordPress.getRestClientUtilsV1_1().get(path, listener, errorListener);
 }
  private void fetchCurrentTheme(final int page) {
    final String siteId = getBlogId();

    WordPress.getRestClientUtils()
        .getCurrentTheme(
            siteId,
            new Listener() {
              @Override
              public void onResponse(JSONObject response) {
                try {
                  Theme theme = Theme.fromJSON(response);
                  if (theme != null) {
                    WordPress.wpDB.setCurrentTheme(siteId, theme.getThemeId());
                    setRefreshing(false, page);
                  }
                } catch (JSONException e) {
                  AppLog.e(T.THEMES, e);
                }
              }
            },
            new ErrorListener() {
              @Override
              public void onErrorResponse(VolleyError response) {}
            });
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();

    if (itemId == R.id.menu_delete) {
      String blogId = String.valueOf(WordPress.getCurrentBlog().getLocalTableBlogId());
      boolean canDeleteMedia = MediaUtils.canDeleteMedia(blogId, getMediaId());
      if (!canDeleteMedia) {
        Toast.makeText(getActivity(), R.string.wait_until_upload_completes, Toast.LENGTH_LONG)
            .show();
        return true;
      }

      Builder builder =
          new AlertDialog.Builder(getActivity())
              .setMessage(R.string.confirm_delete_media)
              .setCancelable(true)
              .setPositiveButton(
                  R.string.delete,
                  new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                      ArrayList<String> ids = new ArrayList<String>(1);
                      ids.add(getMediaId());
                      mCallback.onDeleteMedia(ids);
                    }
                  })
              .setNegativeButton(R.string.cancel, null);
      AlertDialog dialog = builder.create();
      dialog.show();
      return true;
    }

    return super.onOptionsItemSelected(item);
  }
  private synchronized void loadLocalImage(
      ImageView imageView, String filePath, int width, int height) {
    if (MediaUtils.isValidImage(filePath)) {
      imageView.setTag(filePath);

      Bitmap bitmap = WordPress.getBitmapCache().get(filePath);
      if (bitmap != null) {
        imageView.setImageBitmap(bitmap);
      } else {
        BitmapWorkerTask task =
            new BitmapWorkerTask(
                imageView,
                width,
                height,
                new BitmapWorkerCallback() {
                  @Override
                  public void onBitmapReady(String path, ImageView imageView, Bitmap bitmap) {
                    imageView.setImageBitmap(bitmap);
                    WordPress.getBitmapCache().put(path, bitmap);
                  }
                });
        task.execute(filePath);
      }
    }
  }
  private void deleteSelectedComments() {
    if (!NetworkUtils.checkConnection(getActivity())) return;

    final CommentList selectedComments = getCommentAdapter().getSelectedComments();
    getActivity().showDialog(CommentDialogs.ID_COMMENT_DLG_TRASHING);
    CommentActions.OnCommentsModeratedListener listener =
        new CommentActions.OnCommentsModeratedListener() {
          @Override
          public void onCommentsModerated(final CommentList deletedComments) {
            if (!hasActivity()) return;
            finishActionMode();
            dismissDialog(CommentDialogs.ID_COMMENT_DLG_TRASHING);
            if (deletedComments.size() > 0) {
              getCommentAdapter().clearSelectedComments();
              getCommentAdapter().deleteComments(deletedComments);
              if (mOnCommentChangeListener != null)
                mOnCommentChangeListener.onCommentChanged(
                    ChangedFrom.COMMENT_LIST, ChangeType.TRASHED);
            } else {
              ToastUtils.showToast(getActivity(), R.string.error_moderate_comment);
            }
          }
        };

    CommentActions.moderateComments(
        WordPress.getCurrentLocalTableBlogId(), selectedComments, CommentStatus.TRASH, listener);
  }
  /**
   * reply to an individual comment that came from a notification - this differs from
   * submitReplyToComment() in that it enables responding to a reply to a comment this user made on
   * someone else's blog
   */
  static void submitReplyToCommentNote(
      final Note note, final String replyText, final CommentActionListener actionListener) {
    if (note == null || TextUtils.isEmpty(replyText)) {
      if (actionListener != null) actionListener.onActionResult(false);
      return;
    }

    RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            if (actionListener != null) actionListener.onActionResult(true);
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            if (volleyError != null) AppLog.e(T.COMMENTS, volleyError.getMessage(), volleyError);
            if (actionListener != null) actionListener.onActionResult(false);
          }
        };

    Note.Reply reply = note.buildReply(replyText);
    WordPress.getRestClientUtils().replyToComment(reply, listener, errorListener);
  }
  /*
   * get the latest version of this post - note that the post is only considered changed if the
   * like/comment count has changed, or if the current user's like/follow status has changed
   */
  public static void updatePost(
      final ReaderPost originalPost, final UpdateResultListener resultListener) {
    String path =
        "read/sites/" + originalPost.blogId + "/posts/" + originalPost.postId + "/?meta=site,likes";

    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            handleUpdatePostResponse(originalPost, jsonObject, resultListener);
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            AppLog.e(T.READER, volleyError);
            if (resultListener != null) {
              resultListener.onUpdateResult(UpdateResult.FAILED);
            }
          }
        };
    AppLog.d(T.READER, "updating post");
    WordPress.getRestClientUtilsV1_2().get(path, null, null, listener, errorListener);
  }
    @Override
    protected CommentList doInBackground(Void... args) {
      if (!hasActivity()) return null;

      Blog blog = WordPress.getCurrentBlog();
      if (blog == null) {
        isError = true;
        return null;
      }

      // the first time this is called, make sure comments deleted on server are removed
      // from the local database
      if (!mHasCheckedDeletedComments && !isLoadingMore) {
        mHasCheckedDeletedComments = true;
        ApiHelper.removeDeletedComments(blog);
      }

      Map<String, Object> hPost = new HashMap<String, Object>();
      if (isLoadingMore) {
        int numExisting = getCommentAdapter().getCount();
        hPost.put("offset", numExisting);
        hPost.put("number", COMMENTS_PER_PAGE);
      } else {
        hPost.put("number", COMMENTS_PER_PAGE);
      }

      Object[] params = {blog.getRemoteBlogId(), blog.getUsername(), blog.getPassword(), hPost};
      try {
        return ApiHelper.refreshComments(getActivity(), blog, params);
      } catch (Exception e) {
        isError = true;
        return null;
      }
    }
  public static void unregisterDevicePushNotifications(final Context ctx) {
    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            AppLog.d(T.NOTIFS, "Unregister token action succeeded");
            SharedPreferences.Editor editor =
                PreferenceManager.getDefaultSharedPreferences(ctx).edit();
            editor.remove(WPCOM_PUSH_DEVICE_SERVER_ID);
            editor.remove(WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS);
            editor.remove(WPCOM_PUSH_DEVICE_UUID);
            editor.commit();
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            AppLog.e(T.NOTIFS, "Unregister token action failed", volleyError);
          }
        };

    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ctx);
    String deviceID = settings.getString(WPCOM_PUSH_DEVICE_SERVER_ID, null);
    if (TextUtils.isEmpty(deviceID)) {
      return;
    }
    WordPress.getRestClientUtils()
        .post("/devices/" + deviceID + "/delete", listener, errorListener);
  }
  public static void undoBlockBlogFromReader(final BlockedBlogResult blockResult) {
    if (blockResult == null) {
      return;
    }
    if (blockResult.deletedPosts != null) {
      ReaderPostTable.addOrUpdatePosts(null, blockResult.deletedPosts);
    }

    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            boolean success = (jsonObject != null && jsonObject.optBoolean("success"));
            // re-follow the blog if it was being followed prior to the block
            if (success && blockResult.wasFollowing) {
              followBlogById(blockResult.blogId, true, null);
            } else if (!success) {
              AppLog.w(T.READER, "failed to unblock blog " + blockResult.blogId);
            }
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            AppLog.e(T.READER, volleyError);
          }
        };

    AppLog.i(T.READER, "unblocking blog " + blockResult.blogId);
    String path = "me/block/sites/" + Long.toString(blockResult.blogId) + "/delete";
    WordPress.getRestClientUtilsV1_1().post(path, listener, errorListener);
  }
  /** delete multiple comments */
  private static void deleteComments(
      final int accountId,
      final CommentList comments,
      final OnCommentsModeratedListener actionListener) {

    final Blog blog = WordPress.getBlog(accountId);

    if (blog == null || comments == null || comments.size() == 0) {
      if (actionListener != null) actionListener.onCommentsModerated(new CommentList());
      return;
    }

    final CommentList deletedComments = new CommentList();
    final int localBlogId = blog.getLocalTableBlogId();
    final int remoteBlogId = blog.getRemoteBlogId();

    final Handler handler = new Handler();
    new Thread() {
      @Override
      public void run() {
        XMLRPCClientInterface client =
            XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword());

        for (Comment comment : comments) {
          Object[] params = {
            remoteBlogId, blog.getUsername(), blog.getPassword(), comment.commentID
          };

          Object result;
          try {
            result = client.call("wp.deleteComment", params);
            boolean success = (result != null && Boolean.parseBoolean(result.toString()));
            if (success) deletedComments.add(comment);
          } catch (XMLRPCException e) {
            AppLog.e(T.COMMENTS, "Error while deleting comment", e);
          } catch (IOException e) {
            AppLog.e(T.COMMENTS, "Error while deleting comment", e);
          } catch (XmlPullParserException e) {
            AppLog.e(T.COMMENTS, "Error while deleting comment", e);
          }
        }

        // remove successfully deleted comments from SQLite
        CommentTable.deleteComments(localBlogId, deletedComments);

        if (actionListener != null) {
          handler.post(
              new Runnable() {
                @Override
                public void run() {
                  actionListener.onCommentsModerated(deletedComments);
                }
              });
        }
      }
    }.start();
  }
  /*
   * add a comment for the passed post
   */
  public static void addComment(
      final int accountId,
      final String postID,
      final String commentText,
      final CommentActionListener actionListener) {
    final Blog blog = WordPress.getBlog(accountId);
    if (blog == null || TextUtils.isEmpty(commentText)) {
      if (actionListener != null) actionListener.onActionResult(false);
      return;
    }

    final Handler handler = new Handler();

    new Thread() {
      @Override
      public void run() {
        XMLRPCClientInterface client =
            XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword());

        Map<String, Object> commentHash = new HashMap<String, Object>();
        commentHash.put("content", commentText);
        commentHash.put("author", "");
        commentHash.put("author_url", "");
        commentHash.put("author_email", "");

        Object[] params = {
          blog.getRemoteBlogId(), blog.getUsername(), blog.getPassword(), postID, commentHash
        };

        int newCommentID;
        try {
          newCommentID = (Integer) client.call("wp.newComment", params);
        } catch (XMLRPCException e) {
          AppLog.e(T.COMMENTS, "Error while sending new comment", e);
          newCommentID = -1;
        } catch (IOException e) {
          AppLog.e(T.COMMENTS, "Error while sending new comment", e);
          newCommentID = -1;
        } catch (XmlPullParserException e) {
          AppLog.e(T.COMMENTS, "Error while sending new comment", e);
          newCommentID = -1;
        }

        final boolean succeeded = (newCommentID >= 0);

        if (actionListener != null) {
          handler.post(
              new Runnable() {
                @Override
                public void run() {
                  actionListener.onActionResult(succeeded);
                }
              });
        }
      }
    }.start();
  }
Example #20
0
 protected boolean run() {
   Blog currentBlog = WordPress.getCurrentBlog();
   if (currentBlog != null) {
     new ApiHelper.RefreshBlogContentTask(currentBlog, null)
         .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, false);
     return true;
   }
   return false;
 }
  public static boolean followBlogById(
      final long blogId, final boolean isAskingToFollow, final ActionListener actionListener) {
    if (blogId == 0) {
      if (actionListener != null) {
        actionListener.onActionResult(false);
      }
      return false;
    }

    ReaderBlogTable.setIsFollowedBlogId(blogId, isAskingToFollow);
    ReaderPostTable.setFollowStatusForPostsInBlog(blogId, isAskingToFollow);

    if (isAskingToFollow) {
      AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_BLOG_FOLLOWED, blogId);
    } else {
      AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_BLOG_UNFOLLOWED, blogId);
    }

    final String actionName = (isAskingToFollow ? "follow" : "unfollow");
    final String path =
        "sites/" + blogId + "/follows/" + (isAskingToFollow ? "new" : "mine/delete");

    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            boolean success = isFollowActionSuccessful(jsonObject, isAskingToFollow);
            if (success) {
              AppLog.d(T.READER, "blog " + actionName + " succeeded");
            } else {
              AppLog.w(
                  T.READER,
                  "blog " + actionName + " failed - " + jsonToString(jsonObject) + " - " + path);
              localRevertFollowBlogId(blogId, isAskingToFollow);
            }
            if (actionListener != null) {
              actionListener.onActionResult(success);
            }
          }
        };
    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            AppLog.w(T.READER, "blog " + actionName + " failed with error");
            AppLog.e(T.READER, volleyError);
            localRevertFollowBlogId(blogId, isAskingToFollow);
            if (actionListener != null) {
              actionListener.onActionResult(false);
            }
          }
        };
    WordPress.getRestClientUtilsV1_1().post(path, listener, errorListener);

    return true;
  }
 /**
  * Utility method to refresh mixpanel metadata.
  *
  * @param username WordPress.com username
  * @param email WordPress.com email address
  */
 public static void refreshMetadata(String username, String email) {
   SharedPreferences preferences =
       PreferenceManager.getDefaultSharedPreferences(WordPress.getContext());
   int sessionCount = preferences.getInt(AnalyticsTrackerMixpanel.SESSION_COUNT, 0);
   boolean isUserConnected = AccountHelper.isSignedIn();
   boolean isWordPressComUser = AccountHelper.isSignedInWordPressDotCom();
   boolean isJetpackUser = AccountHelper.isJetPackUser();
   int numBlogs = WordPress.wpDB.getVisibleBlogs().size();
   int versionCode = PackageUtils.getVersionCode(WordPress.getContext());
   AnalyticsTracker.refreshMetadata(
       isUserConnected,
       isWordPressComUser,
       isJetpackUser,
       sessionCount,
       numBlogs,
       versionCode,
       username,
       email);
 }
  private void moderateSelectedComments(final CommentStatus newStatus) {
    final CommentList selectedComments = getCommentAdapter().getSelectedComments();
    final CommentList updateComments = new CommentList();

    // build list of comments whose status is different than passed
    for (Comment comment : selectedComments) {
      if (comment.getStatusEnum() != newStatus) updateComments.add(comment);
    }
    if (updateComments.size() == 0) return;

    if (!NetworkUtils.checkConnection(getActivity())) return;

    final int dlgId;
    switch (newStatus) {
      case APPROVED:
        dlgId = CommentDialogs.ID_COMMENT_DLG_APPROVING;
        break;
      case UNAPPROVED:
        dlgId = CommentDialogs.ID_COMMENT_DLG_UNAPPROVING;
        break;
      case SPAM:
        dlgId = CommentDialogs.ID_COMMENT_DLG_SPAMMING;
        break;
      case TRASH:
        dlgId = CommentDialogs.ID_COMMENT_DLG_TRASHING;
        break;
      default:
        return;
    }
    getActivity().showDialog(dlgId);

    CommentActions.OnCommentsModeratedListener listener =
        new CommentActions.OnCommentsModeratedListener() {
          @Override
          public void onCommentsModerated(final CommentList moderatedComments) {
            if (!hasActivity()) return;
            finishActionMode();
            dismissDialog(dlgId);
            if (moderatedComments.size() > 0) {
              getCommentAdapter().clearSelectedComments();
              getCommentAdapter().replaceComments(moderatedComments);
              if (mOnCommentChangeListener != null) {
                ChangeType changeType =
                    (newStatus == CommentStatus.TRASH ? ChangeType.TRASHED : ChangeType.STATUS);
                mOnCommentChangeListener.onCommentChanged(ChangedFrom.COMMENT_LIST, changeType);
              }
            } else {
              ToastUtils.showToast(getActivity(), R.string.error_moderate_comment);
            }
          }
        };

    CommentActions.moderateComments(
        WordPress.getCurrentLocalTableBlogId(), updateComments, newStatus, listener);
  }
  public static void getPushNotificationSettings(
      Context context, RestRequest.Listener listener, RestRequest.ErrorListener errorListener) {
    if (!WordPress.hasValidWPComCredentials(context)) {
      return;
    }

    String gcmToken = GCMRegistrar.getRegistrationId(context);
    if (TextUtils.isEmpty(gcmToken)) {
      return;
    }

    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
    String deviceID = settings.getString(WPCOM_PUSH_DEVICE_SERVER_ID, null);
    if (TextUtils.isEmpty(deviceID)) {
      AppLog.e(T.NOTIFS, "device_ID is null in preferences. Get device settings skipped.");
      return;
    }

    WordPress.getRestClientUtils().get("/device/" + deviceID, listener, errorListener);
  }
 @Override
 public void onItemSelected(IcsAdapterView<?> arg0, View arg1, int position, long arg3) {
   // http://stackoverflow.com/questions/5624825/spinner-onitemselected-executes-when-it-is-not-suppose-to/5918177#5918177
   if (!mBlogSpinnerInitialized) {
     mBlogSpinnerInitialized = true;
   } else {
     WordPress.setCurrentBlog(blogIDs[position]);
     updateMenuDrawer();
     onBlogChanged();
   }
 }
  /**
   * Setup the global state tracking which blog is currently active.
   *
   * <p>If the global state is not already set, try and determine the last active blog from the last
   * time the application was used. If we're not able to determine the last active blog, just select
   * the first one.
   *
   * <p>If no blogs are configured, display the "new account" activity to allow the user to setup a
   * blog.
   */
  public void setupCurrentBlog() {
    Blog currentBlog = WordPress.getCurrentBlog();

    // no blogs are configured, so display new account activity
    if (currentBlog == null) {
      Log.d(TAG, "No accounts configured.  Sending user to set up an account");
      mShouldFinish = false;
      Intent i = new Intent(this, NewAccountActivity.class);
      startActivityForResult(i, ADD_ACCOUNT_REQUEST);
      return;
    }
  }
    @Override
    protected void onPostExecute(Boolean postUploadedSuccessfully) {
      if (postUploadedSuccessfully) {
        WordPress.postUploaded(post.getRemotePostId());
        nm.cancel(notificationID);
        WordPress.wpDB.deleteMediaFilesForPost(post);
      } else {
        String postOrPage =
            (String)
                (post.isPage()
                    ? context.getResources().getText(R.string.page_id)
                    : context.getResources().getText(R.string.post_id));
        Intent notificationIntent =
            new Intent(context, post.isPage() ? PagesActivity.class : PostsActivity.class);
        notificationIntent.addFlags(
            Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK
                | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
        notificationIntent.setAction(Intent.ACTION_MAIN);
        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        notificationIntent.setData(
            (Uri.parse("custom://wordpressNotificationIntent" + post.getLocalTableBlogId())));
        notificationIntent.putExtra(PostsActivity.EXTRA_VIEW_PAGES, post.isPage());
        notificationIntent.putExtra(PostsActivity.EXTRA_ERROR_MSG, mErrorMessage);
        if (mErrorUnavailableVideoPress) {
          notificationIntent.putExtra(
              PostsActivity.EXTRA_ERROR_INFO_TITLE, getString(R.string.learn_more));
          notificationIntent.putExtra(PostsActivity.EXTRA_ERROR_INFO_LINK, Constants.videoPressURL);
        }
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent =
            PendingIntent.getActivity(
                context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        n.flags |= Notification.FLAG_AUTO_CANCEL;
        n.icon = android.R.drawable.stat_notify_error;
        String errorText = context.getResources().getText(R.string.upload_failed).toString();
        if (mIsMediaError)
          errorText =
              context.getResources().getText(R.string.media)
                  + " "
                  + context.getResources().getText(R.string.error);
        n.setLatestEventInfo(
            context,
            (mIsMediaError) ? errorText : context.getResources().getText(R.string.upload_failed),
            (mIsMediaError) ? mErrorMessage : postOrPage + " " + errorText + ": " + mErrorMessage,
            pendingIntent);

        nm.notify(notificationID, n); // needs a unique id
      }

      postUploaded();
    }
  /** like/unlike the passed post */
  public static boolean performLikeAction(final ReaderPost post, final boolean isAskingToLike) {
    // do nothing if post's like state is same as passed
    boolean isCurrentlyLiked = ReaderPostTable.isPostLikedByCurrentUser(post);
    if (isCurrentlyLiked == isAskingToLike) {
      AppLog.w(T.READER, "post like unchanged");
      return false;
    }

    // update like status and like count in local db
    int numCurrentLikes = ReaderPostTable.getNumLikesForPost(post.blogId, post.postId);
    int newNumLikes = (isAskingToLike ? numCurrentLikes + 1 : numCurrentLikes - 1);
    if (newNumLikes < 0) {
      newNumLikes = 0;
    }
    ReaderPostTable.setLikesForPost(post, newNumLikes, isAskingToLike);
    ReaderLikeTable.setCurrentUserLikesPost(post, isAskingToLike);

    final String actionName = isAskingToLike ? "like" : "unlike";
    String path = "sites/" + post.blogId + "/posts/" + post.postId + "/likes/";
    if (isAskingToLike) {
      path += "new";
    } else {
      path += "mine/delete";
    }

    com.wordpress.rest.RestRequest.Listener listener =
        new RestRequest.Listener() {
          @Override
          public void onResponse(JSONObject jsonObject) {
            AppLog.d(T.READER, String.format("post %s succeeded", actionName));
          }
        };

    RestRequest.ErrorListener errorListener =
        new RestRequest.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            String error = VolleyUtils.errStringFromVolleyError(volleyError);
            if (TextUtils.isEmpty(error)) {
              AppLog.w(T.READER, String.format("post %s failed", actionName));
            } else {
              AppLog.w(T.READER, String.format("post %s failed (%s)", actionName, error));
            }
            AppLog.e(T.READER, volleyError);
            ReaderPostTable.setLikesForPost(post, post.numLikes, post.isLikedByCurrentUser);
            ReaderLikeTable.setCurrentUserLikesPost(post, post.isLikedByCurrentUser);
          }
        };

    WordPress.getRestClientUtilsV1_1().post(path, listener, errorListener);
    return true;
  }
  @Override
  protected void onResume() {
    super.onResume();
    if (areThemesAccessible()) {
      mIsRunning = true;

      // fetch themes if we don't have any
      if (WordPress.getCurrentBlog() != null && WordPress.wpDB.getThemeCount(getBlogId()) == 0) {
        fetchThemes(mViewPager.getCurrentItem());
        setRefreshing(true, mViewPager.getCurrentItem());
      }
    }
  }
 public static ReaderDatabase getDatabase() {
   if (mReaderDb == null) {
     synchronized (mDbLock) {
       if (mReaderDb == null) {
         mReaderDb = new ReaderDatabase(WordPress.getContext());
         // this ensures that onOpen() is called with a writable database (open will fail if app
         // calls getReadableDb() first)
         mReaderDb.getWritableDatabase();
       }
     }
   }
   return mReaderDb;
 }