commit bfbed4b532531a58e0679400f35e245acddfce60
Author: みぞ@CrazyBeatCoder <mizo0203@mizo0203.com>
Date:   Tue Aug 14 19:04:32 2018 +0900

    Change API to request Twitter timeline from User Streams API to statuses/home_timeline API. fix #334 @2.25h

diff --git a/TwitterTimelineTalker.iml b/TwitterTimelineTalker.iml
index bceb6db..45f0e10 100644
--- a/TwitterTimelineTalker.iml
+++ b/TwitterTimelineTalker.iml
@@ -10,6 +10,5 @@
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="Maven: org.twitter4j:twitter4j-core:4.0.6" level="project" />
-    <orderEntry type="library" name="Maven: org.twitter4j:twitter4j-stream:4.0.6" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b4ba65d..3e40809 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,10 +40,5 @@
 			<artifactId>twitter4j-core</artifactId>
 			<version>[4.0,)</version>
 		</dependency>
-		<dependency>
-			<groupId>org.twitter4j</groupId>
-			<artifactId>twitter4j-stream</artifactId>
-			<version>[4.0,)</version>
-		</dependency>
 	</dependencies>
 </project>
diff --git a/src/com/mizo0203/twitter/timeline/talker/TwitterTimelineTalker.java b/src/com/mizo0203/twitter/timeline/talker/TwitterTimelineTalker.java
index cb4d47f..70acec6 100644
--- a/src/com/mizo0203/twitter/timeline/talker/TwitterTimelineTalker.java
+++ b/src/com/mizo0203/twitter/timeline/talker/TwitterTimelineTalker.java
@@ -1,15 +1,15 @@
 package com.mizo0203.twitter.timeline.talker;
 
+import twitter4j.*;
+import twitter4j.conf.Configuration;
+
+import java.util.Collections;
 import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import twitter4j.StallWarning;
-import twitter4j.Status;
-import twitter4j.StatusDeletionNotice;
-import twitter4j.StatusListener;
-import twitter4j.TwitterStream;
-import twitter4j.TwitterStreamFactory;
-import twitter4j.conf.Configuration;
 
 public class TwitterTimelineTalker {
 
@@ -18,19 +18,11 @@ public class TwitterTimelineTalker {
    */
   public static final String LANG_JA = Locale.JAPAN.getLanguage();
 
-  private Talker.YukkuriVoice mYukkuriVoice = Talker.YukkuriVoice.REIMU;
-  private final TwitterStream mTwitterStream;
-  private final Talker mTalker;
+  private final RequestHomeTimelineTimerTask mRequestHomeTimelineTimerTask;
 
   public TwitterTimelineTalker(Configuration configuration, Talker talker) {
-    mTwitterStream = new TwitterStreamFactory(configuration).getInstance();
-    mTwitterStream.addListener(new OnStatusEvent());
-    mTalker = talker;
-  }
-
-  public void start() {
-    // OnStatusEvent に Twitter タイムラインが通知される
-    mTwitterStream.user();
+    Twitter twitter = new TwitterFactory(configuration).getInstance();
+    mRequestHomeTimelineTimerTask = new RequestHomeTimelineTimerTask(twitter, talker);
   }
 
   private static String getUserNameWithoutContext(String name) {
@@ -39,9 +31,64 @@ public class TwitterTimelineTalker {
     return m.replaceFirst("$1");
   }
 
-  private class OnStatusEvent implements StatusListener {
+  public void start() {
+    new Timer().schedule(mRequestHomeTimelineTimerTask, 0L, TimeUnit.MINUTES.toMillis(1));
+  }
+
+  private static class RequestHomeTimelineTimerTask extends TimerTask {
+
+    private static final int HOME_TIMELINE_COUNT_MAX = 200;
+    private static final int HOME_TIMELINE_COUNT_MIN = 1;
+
+    private final Twitter mTwitter;
+    private final Talker mTalker;
+
+    private Talker.YukkuriVoice mYukkuriVoice = Talker.YukkuriVoice.REIMU;
+
+    /**
+     * mStatusSinceId より大きい（つまり、より新しい） ID を持つ HomeTimeline をリクエストする
+     */
+    private long mStatusSinceId = 1L;
+
+    private boolean mIsUpdatedStatusSinceId = false;
+
+    private RequestHomeTimelineTimerTask(Twitter twitter, Talker talker) {
+      mTwitter = twitter;
+      mTalker = talker;
+    }
+
+    /**
+     * The action to be performed by this timer task.
+     */
+    @Override
+    public void run() {
+      try {
+        // mStatusSinceId が未更新ならば、 Status を 1 つだけ取得する
+        int count = mIsUpdatedStatusSinceId ? HOME_TIMELINE_COUNT_MAX : HOME_TIMELINE_COUNT_MIN;
+        Paging paging = new Paging(1, count, mStatusSinceId);
+        ResponseList<Status> statusResponseList = mTwitter.getHomeTimeline(paging);
+
+        if (statusResponseList.isEmpty()) {
+          return;
+        }
+
+        // mStatusSinceId を、取得した最新の ID に更新する
+        mStatusSinceId = statusResponseList.get(0).getId();
+        mIsUpdatedStatusSinceId = true;
+
+        // Status が古い順になるよう、 statusResponseList を逆順に並び替える
+        Collections.reverse(statusResponseList);
+
+        for (Status status : statusResponseList) {
+          onStatus(status);
+        }
+
+      } catch (TwitterException e) {
+        e.printStackTrace();
+      }
+    }
 
-    public void onStatus(final Status status) {
+    private void onStatus(final Status status) {
       if (!LANG_JA.equalsIgnoreCase(status.getLang())) {
         return;
       }
@@ -66,27 +113,6 @@ public class TwitterTimelineTalker {
       } else {
         mYukkuriVoice = Talker.YukkuriVoice.REIMU;
       }
-
-    }
-
-    public void onDeletionNotice(StatusDeletionNotice sdn) {
-      System.err.println("onDeletionNotice.");
-    }
-
-    public void onTrackLimitationNotice(int i) {
-      System.err.println("onTrackLimitationNotice.(" + i + ")");
-    }
-
-    public void onScrubGeo(long lat, long lng) {
-      System.err.println("onScrubGeo.(" + lat + ", " + lng + ")");
-    }
-
-    public void onException(Exception excptn) {
-      System.err.println("onException.");
     }
-
-    @Override
-    public void onStallWarning(StallWarning arg0) {}
   }
-
 }
