十分な牽引力なしに投稿を編集する

1概要

  • Redditへの投稿はがらくたのシュートです 別の、多分より良い投稿はまったく愛を得ることはありませんが、一方の投稿は素晴らしいことをし、全体の多くの注目を集めるかもしれません。早い段階でこれらの投稿を監視し、十分な牽引力が得られない場合は、 すばやく削除して再送信します。

この素早い記事では、リンクを続けています:/case-study-a-reddit-app-with-spring[Redditのケーススタディ]興味深い機能を実装することで - すぐに十分な注目を集めていない場合は 投稿を削除して再送信

単純な目標は、投稿がある程度の時間内にそれを残すのに十分な牽引力を得ていると見なすのに十分な数のRedditへの投票でユーザーが設定できるようにすることです。

2その他のReddit権限

まず、Reddit APIから 追加の許可を求める 必要があります - 具体的には投稿を編集する必要があります。

そこで、Redditの Resource に“ edit ”スコープを追加します。

@Bean
public OAuth2ProtectedResourceDetails reddit() {
    AuthorizationCodeResourceDetails details =
      new AuthorizationCodeResourceDetails();
    details.setScope(Arrays.asList("identity", "read", "submit", "edit"));
    ...
}

** 3エンティティとリポジトリ

**

それでは、 Post エンティティに追加情報を追加しましょう。

@Entity
public class Post {
    ...
    private String redditID;
    private int noOfAttempts;
    private int timeInterval;
    private int minScoreRequired;
}

フィールド:

  • redditID :スコアをチェックするときに使われるRedditの投稿ID

投稿を削除するとき noOfAttempts ** :再送信の最大試行回数(投稿を削除して

再送信してください) timeInterval ** :投稿が十分になっているかどうかをチェックする時間間隔

牽引力 minScoreRequired ** :成功したと見なすために必要な最小スコア

諦めるのに十分

次に、 PostRepository インターフェースにいくつかの新しい操作を追加しましょう。それらを確認する必要があるときに簡単に投稿を取得するためです。

public interface PostRepository extends JpaRepository<Post, Long> {

    List<Post> findBySubmissionDateBeforeAndIsSent(Date date, boolean sent);

    List<Post> findByUser(User user);

    List<Post> findByRedditIDNotNullAndNoOfAttemptsGreaterThan(int attempts);
}

** 4新しいスケジュールされたタスク

**

それでは - 新しいタスク - 再送信タスク - をスケジューラに定義しましょう。

@Scheduled(fixedRate = 3 **  60 **  1000)
public void checkAndReSubmitPosts() {
    List<Post> submitted =
      postReopsitory.findByRedditIDNotNullAndNoOfAttemptsGreaterThan(0);
    for (Post post : submitted) {
        checkAndReSubmit(post);
    }
}

数分ごとに、これは単純にまだ進行中の投稿を繰り返すことです - そして、それらが十分な牽引力を得ていない場合、それはそれらを削除してそれらを再び送信します。

そして、これが checkAndReSubmit() メソッドです。

private void checkAndReSubmit(Post post) {
    try {
        checkAndReSubmitInternal(post);
    } catch (final Exception e) {
        logger.error("Error occurred while check post " + post.toString(), e);
    }
}
private void checkAndReSubmitInternal(Post post) {
    if (didIntervalPassed(post.getSubmissionDate(), post.getTimeInterval())) {
        int score = getPostScore(post.getRedditID());
        if (score < post.getMinScoreRequired()) {
            deletePost(post.getRedditID());
            resetPost(post);
        } else {
            post.setNoOfAttempts(0);
            postReopsitory.save(post);
        }
    }
}
private boolean didIntervalPassed(Date submissonDate, int postInterval) {
    long currentTime = new Date().getTime();
    long interval = currentTime - submissonDate.getTime();
    long intervalInMinutes = TimeUnit.MINUTES.convert(interval, TimeUnit.MILLISECONDS);
    return intervalInMinutes > postInterval;
}
private void resetPost(Post post) {
    long time = new Date().getTime();
    time += TimeUnit.MILLISECONDS.convert(post.getTimeInterval(), TimeUnit.MINUTES);
    post.setRedditID(null);
    post.setSubmissionDate(new Date(time));
    post.setSent(false);
    post.setSubmissionResponse("Not sent yet");
    postReopsitory.save(post);
}

最初にRedditに送信するときにも、 redditID を追跡する必要があります。

private void submitPostInternal(Post post) {
    ...
    JsonNode node = redditRestTemplate.postForObject(
      "https://oauth.reddit.com/api/submit", param, JsonNode.class);
    JsonNode errorNode = node.get("json").get("errors").get(0);
    if (errorNode == null) {
        post.setRedditID(node.get("json").get("data").get("id").asText());
        post.setNoOfAttempts(post.getNoOfAttempts() - 1);
        ...
}

ここのロジックも非常に単純です。IDを保存し、試行回数カウンターを減らすだけです。

5 Reddit Postのスコアを取得してください

では、Redditから現在の投稿のスコアを取得する方法を見てみましょう。

private int getPostScore(String redditId) {
    JsonNode node = redditRestTemplate.getForObject(
      "https://oauth.reddit.com/api/info?id=t3__" + redditId, JsonNode.class);
    int score = node.get("data").get("children").get(0).get("data").get("score").asInt();
    return score;
}

ご了承ください:

  • 投稿情報を取得するときは " read "スコープが必要

Reddit ** 取得するためにreddit IDに「 t3 __」を追加します

投稿のhttp://www.reddit.com/dev/api#fullnames[完全な名前]

6. Reddit Postを削除します.

次に、そのIDを使用してReddit投稿を削除する方法を見てみましょう。

private void deletePost(String redditId) {
    MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>();
    param.add("id", "t3__" + redditId);
    redditRestTemplate.postForObject(
      "https://oauth.reddit.com/api/del.json", param, JsonNode.class);
}

7. RedditController

それでは、新しい情報をコントローラに追加しましょう。

@RequestMapping(value = "/schedule", method = RequestMethod.POST)
public String schedule(Model model,
  @RequestParam Map<String, String> formParams) throws ParseException {
    Post post = new Post();
    post.setTitle(formParams.get("title"));
    post.setSubreddit(formParams.get("sr"));
    post.setUrl(formParams.get("url"));
    post.setNoOfAttempts(Integer.parseInt(formParams.get("attempt")));
    post.setTimeInterval(Integer.parseInt(formParams.get("interval")));
    post.setMinScoreRequired(Integer.parseInt(formParams.get("score")));
    ....
}

8 UI - ルールを設定する

最後に、新しい設定を再送信するように非常に簡単なスケジュールフォームを変更しましょう。

<label class="col-sm-3">Resubmit Settings</label>

<label>Number of Attempts</label>
<select name="attempt">
    <option value="0" selected>None</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
</select>

<label>Time interval</label>
<select name="interval">
    <option value="0" selected >None</option>
    <option value="45">45 minutes</option>
    <option value="60">1 hour</option>
    <option value="120">2 hours</option>
</select>

<label>Min score</label>
<input type="number"value="0" name="score" required/>

9結論

この単純なアプリでできることを改善し続けています - 今すぐRedditに投稿できます - 投稿が十分な勢いで得られない場合は - システムに削除してもらい、再投稿してもらう機会を増やすことができます。実行しています。