OSDN Git Service

Twitter4jのバージョンアップ,及びtwitter4j仕様変更への対応.
[nt-manager/nt-manager.git] / src / twitter / manage / TweetManager.java
1 package twitter.manage;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.Date;
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.Properties;
17 import java.util.logging.Level;
18 import java.util.logging.Logger;
19
20 import twitter.log.TwitterLogManager;
21 import twitter4j.Annotations;
22 import twitter4j.DirectMessage;
23 import twitter4j.GeoLocation;
24 import twitter4j.HashtagEntity;
25 import twitter4j.PagableResponseList;
26 import twitter4j.Paging;
27 import twitter4j.Place;
28 import twitter4j.Query;
29 import twitter4j.QueryResult;
30 import twitter4j.RateLimitStatus;
31 import twitter4j.Status;
32 import twitter4j.StatusUpdate;
33 import twitter4j.Tweet;
34 import twitter4j.Twitter;
35 import twitter4j.TwitterException;
36 import twitter4j.TwitterFactory;
37 import twitter4j.URLEntity;
38 import twitter4j.User;
39 import twitter4j.UserList;
40 import twitter4j.UserMentionEntity;
41 import twitter4j.conf.Configuration;
42 import twitter4j.conf.ConfigurationBuilder;
43 import twitter4j.auth.*;
44
45 public class TweetManager {
46
47         /**
48          * DirectMessageのユーザ情報等からステータスを生成
49          * 
50          * @author nishio
51          * 
52          */
53         private class DirectMessageUserStatus implements Status {
54
55                 /**
56          *
57          */
58                 private static final long serialVersionUID = 1L;
59                 // 受信したdirectMessageの情報
60                 private DirectMessage message = null;
61                 // ユーザ情報
62                 private User user = null;
63
64                 public DirectMessageUserStatus(DirectMessage directMessage, User user) {
65                         this.message = directMessage;
66                         this.user = user;
67                 }
68
69                 @Override
70                 public String[] getContributors() {
71                         return null;
72                 }
73
74                 @Override
75                 public Date getCreatedAt() {
76                         return message.getCreatedAt();
77                 }
78
79                 @Override
80                 public GeoLocation getGeoLocation() {
81                         return null;
82                 }
83
84                 @Override
85                 public long getId() {
86                         return user.getId();
87                 }
88
89                 @Override
90                 public String getInReplyToScreenName() {
91                         return ((SimpleUser) user).getStatusInReplyToScreenName();
92                 }
93
94                 @Override
95                 public long getInReplyToStatusId() {
96                         return ((SimpleUser) user).getStatusInReplyToUserId();
97                 }
98
99                 @Override
100                 public long getInReplyToUserId() {
101                         return 0;
102                 }
103
104                 @Override
105                 public Place getPlace() {
106                         return null;
107                 }
108
109                 @Override
110                 public RateLimitStatus getRateLimitStatus() {
111                         return user.getRateLimitStatus();
112                 }
113
114                 @Override
115                 public Status getRetweetedStatus() {
116                         return null;
117                 }
118
119                 @Override
120                 public String getSource() {
121                         return "Unknown";
122                 }
123
124                 @Override
125                 public String getText() {
126                         return message.getText();
127                 }
128
129                 @Override
130                 public User getUser() {
131                         return user;
132                 }
133
134                 @Override
135                 public boolean isFavorited() {
136                         return ((SimpleUser) user).isStatusFavorited();
137                 }
138
139                 @Override
140                 public boolean isRetweet() {
141                         return false;
142                 }
143
144                 @Override
145                 public boolean isTruncated() {
146                         return false;
147                 }
148
149                 public int compareTo(Status t) {
150                         throw new UnsupportedOperationException("Not supported yet.");
151                 }
152
153                 @Override
154                 public Annotations getAnnotations() {
155                         // TODO 自動生成されたメソッド・スタブ
156                         return null;
157                 }
158
159                 @Override
160                 public HashtagEntity[] getHashtagEntities() {
161                         // TODO 自動生成されたメソッド・スタブ
162                         return null;
163                 }
164
165                 @Override
166                 public long getRetweetCount() {
167                         // TODO 自動生成されたメソッド・スタブ
168                         return 0;
169                 }
170
171                 @Override
172                 public URLEntity[] getURLEntities() {
173                         // TODO 自動生成されたメソッド・スタブ
174                         return null;
175                 }
176
177                 @Override
178                 public UserMentionEntity[] getUserMentionEntities() {
179                         // TODO 自動生成されたメソッド・スタブ
180                         return null;
181                 }
182
183                 @Override
184                 public boolean isRetweetedByMe() {
185                         // TODO 自動生成されたメソッド・スタブ
186                         return false;
187                 }
188         }
189
190         private Twitter twitter = null;
191         // クライアントのConsumer Key
192         private static final String CONSUMER_KEY = "tbo5erit2M2ZzN6n8tEYcA";
193         // クライアントのConsumer Secret 外部に漏れてはいけない
194         private static final String CONSUMER_SECRET = "tODurbdySLYU1pKjtB3MQTDRBGy562dHzVf7d62mm8";
195         // accessToken
196         private String accessToken = "";
197         // secretToken 外部に漏れてはいけない
198         private String secretToken = "";
199         // 設定ファイル保存ディレクトリ名
200         private static final String PROPERTIES_DIRECTORY = TweetConfiguration.PROPERTIES_DIRECTORY;
201         // 設定ファイル保存ファイル名
202         private static final String TWEET_INFO_FILENAME = TweetConfiguration.TWEET_INFO_FILENAME;
203         // アカウント情報保存ファイル名
204         private static final String ACCOUNT_INFORMATION_FILENAME = TweetConfiguration.ACCOUNT_INFORMATION_FILENAME;
205         // 一度に取得する最大のtweet数
206         private final int MAX_TWEET_NUM = 99;
207         // 前回取得したtweetの情報
208         private long sinceTweetID = 0;
209         // 前回取得したmentionのtweetID
210         private long sinceMentionID = 0;
211         // 前回取得したsendDirectMessageの情報
212         private long sinceSendDirectMessageID = 0;
213         // 前回取得したdirectMessageの情報
214         private long sinceDirectMessageID = 0;
215         // 設定ファイル
216         private Properties property = null;
217         // アカウント設定ファイル
218         private Properties accountProperty = null;
219         // ログ保存
220         private TwitterLogManager logManager = null;
221
222         public TweetManager() {
223                 logManager = new TwitterLogManager();
224         }
225
226         /**
227          * 設定ファイルを読み込む
228          * 
229          * @throws IOException
230          * @throws FileNotFoundException
231          */
232         public void loadProperties() throws FileNotFoundException, IOException {
233                 if (property == null) {
234                         this.property = new Properties();
235                 }
236                 property.load(new FileInputStream("./" + PROPERTIES_DIRECTORY + "/"
237                                 + TWEET_INFO_FILENAME));
238                 // 設定読み込み
239                 String sti = this.property.getProperty("sinceTweetID");
240                 /*
241                  * String smi = this.property.getProperty("sinceMentionID"); String
242                  * ssdmi = this.property.getProperty("sinceSendDirectMessageID"); String
243                  * sdmi = this.property.getProperty("sinceDirectMessageID");
244                  */
245
246                 try {
247                         this.sinceTweetID = Long.parseLong(sti);
248                         /*
249                          * this.sinceMentionID = Long.parseLong(smi);
250                          * this.sinceSendDirectMessageID = Long.parseLong(ssdmi);
251                          * this.sinceDirectMessageID = Long.parseLong(sdmi);
252                          */
253                 } catch (NumberFormatException e) {
254                         e.printStackTrace();
255                 }
256         }
257
258         /**
259          * 設定ファイルを保存する
260          * 
261          * @throws IOException
262          */
263         public void saveProperties() throws IOException {
264                 // 設定ファイルディレクトリを作成
265                 File logDir = new File("./" + PROPERTIES_DIRECTORY);
266                 if (!logDir.exists()) {
267                         // ディレクトリが存在しないので作成する
268                         if (logDir.mkdir() == false) {
269                                 throw new IOException(PROPERTIES_DIRECTORY
270                                                 + "ディレクトリを作成できませんでした.");
271                         }
272                 }
273                 if (property == null) {
274                         this.property = new Properties();
275                 }
276                 // since idを保存
277                 this.property.setProperty("sinceTweetID", sinceTweetID + "");
278                 /*
279                  * this.property.setProperty("sinceMentionID", sinceMentionID + "");
280                  * this.property.setProperty("sinceSendDirectMessageID",
281                  * sinceSendDirectMessageID + "");
282                  * this.property.setProperty("sinceDirectMessageID",
283                  * sinceDirectMessageID + "");
284                  */
285                 // プロパティのリストを保存
286                 property.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY + "/"
287                                 + TWEET_INFO_FILENAME), null);
288         }
289
290         /**
291          * アカウント情報を読み込む
292          * 
293          * @throws FileNotFoundException
294          * @throws IOException
295          */
296         public void loadAccountProperties() throws FileNotFoundException,
297                         IOException {
298                 if (accountProperty == null) {
299                         this.accountProperty = new Properties();
300                 }
301                 accountProperty.load(new FileInputStream("./" + PROPERTIES_DIRECTORY
302                                 + "/" + ACCOUNT_INFORMATION_FILENAME));
303                 // 設定読み込み
304                 this.accessToken = this.accountProperty.getProperty("accessToken");
305                 this.secretToken = this.accountProperty.getProperty("secretToken");
306         }
307
308         /**
309          * アカウント情報を保存する
310          * 
311          * @throws IOException
312          */
313         public void saveAccountProperties() throws IOException {
314                 // 設定ファイルディレクトリを作成
315                 File logDir = new File("./" + PROPERTIES_DIRECTORY);
316                 if (!logDir.exists()) {
317                         // ディレクトリが存在しないので作成する
318                         if (logDir.mkdir() == false) {
319                                 throw new IOException(PROPERTIES_DIRECTORY
320                                                 + "ディレクトリを作成できませんでした.");
321                         }
322                 }
323                 if (accountProperty == null) {
324                         this.accountProperty = new Properties();
325                 }
326                 // since idを保存
327                 this.accountProperty.setProperty("accessToken", this.accessToken);
328                 this.accountProperty.setProperty("secretToken", this.secretToken);
329                 // プロパティのリストを保存
330                 accountProperty.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY
331                                 + "/" + ACCOUNT_INFORMATION_FILENAME), null);
332         }
333
334         /**
335          * 受信したダイレクトメッセージを取得
336          * 
337          * @param num
338          * @return
339          * @throws TwitterException
340          */
341         public List<Status> getDirectMessages(int num) throws TwitterException {
342                 List<DirectMessage> directMessages = twitter
343                                 .getDirectMessages(new Paging(1, num));
344                 // Tweetの一覧
345                 List<Status> messageList = new LinkedList<Status>();
346
347                 if (directMessages != null && directMessages.size() > 0) {
348                         // tweetIDを保存しておく
349                         this.sinceDirectMessageID = directMessages.get(0).getId();
350                         // 一番新しいtweetを一番したに持ってくる
351                         for (DirectMessage message : directMessages) {
352                                 User user = message.getSender();
353                                 DirectMessageUserStatus status = new DirectMessageUserStatus(
354                                                 message, user);
355                                 messageList.add(0, status);
356                         }
357                 }
358
359                 try {
360                         saveProperties();
361                 } catch (IOException e) {
362                         e.printStackTrace();
363                 }
364                 return messageList;
365         }
366
367         /**
368          * 送信したダイレクトメッセージを取得
369          * 
370          * @param num
371          * @return
372          * @throws TwitterException
373          */
374         public List<Status> getSendDirectMessages(int num) throws TwitterException {
375                 List<DirectMessage> directMessages = twitter
376                                 .getSentDirectMessages(new Paging(1, num));
377                 // Tweetの一覧
378                 List<Status> messageList = new LinkedList<Status>();
379                 if (directMessages != null && directMessages.size() > 0) {
380                         // tweetIDを保存しておく
381                         this.sinceSendDirectMessageID = directMessages.get(0).getId();
382                         // 一番新しいtweetを一番したに持ってくる
383                         for (DirectMessage message : directMessages) {
384                                 User user = message.getRecipient();
385                                 DirectMessageUserStatus status = new DirectMessageUserStatus(
386                                                 message, user);
387                                 messageList.add(0, status);
388                         }
389                 }
390                 try {
391                         saveProperties();
392                 } catch (IOException e) {
393                         e.printStackTrace();
394                 }
395                 return messageList;
396         }
397
398         /**
399          * Mentionの取得
400          * 
401          * @param num
402          * @return
403          * @throws TwitterException
404          */
405         public List<Status> getMentions(int num) throws TwitterException {
406                 List<Status> statuses = twitter.getMentions(new Paging(1, num));
407                 // Tweetの一覧
408                 List<Status> tweetList = new LinkedList<Status>();
409                 if (statuses != null && statuses.size() > 0) {
410                         // tweetIDを保存しておく
411                         this.sinceMentionID = statuses.get(0).getId();
412                         // 一番新しいtweetを一番したに持ってくる
413                         for (Status status : statuses) {
414                                 tweetList.add(0, status);
415                         }
416                 }
417                 try {
418                         saveProperties();
419                 } catch (IOException e) {
420                         e.printStackTrace();
421                 }
422                 return tweetList;
423         }
424
425         /**
426          * まだ取得していないDirectMessageを取得
427          * 
428          * @return
429          * @throws TwitterException
430          */
431         public List<Status> getNewDirectMessages() throws TwitterException {
432                 if (this.sinceDirectMessageID == 0) {
433                         return getDirectMessages(MAX_TWEET_NUM);
434                 }
435                 List<DirectMessage> directMessages = twitter
436                                 .getDirectMessages(new Paging(sinceDirectMessageID));
437                 // もし20件データ取得したらもっとデータがある可能性がある
438                 if (directMessages.size() >= 20) {
439                         List<DirectMessage> ndata = twitter.getDirectMessages(new Paging(1,
440                                         MAX_TWEET_NUM));
441                         ndata = ndata.subList(21, ndata.size());
442                         for (DirectMessage s : ndata) {
443                                 // すでに取得したことのあるデータだったとき
444                                 if (s.getId() <= sinceDirectMessageID) {
445                                         break;
446                                 }
447                                 directMessages.add(s);
448                         }
449                 }
450                 // Tweetの一覧
451                 List<Status> messageList = new LinkedList<Status>();
452                 if (directMessages != null && directMessages.size() > 0) {
453                         // tweetIDを保存しておく
454                         this.sinceDirectMessageID = directMessages.get(0).getId();
455                         // 一番新しいtweetを一番したに持ってくる
456                         for (DirectMessage message : directMessages) {
457                                 Status status = message.getSender().getStatus();
458                                 messageList.add(0, status);
459                         }
460                 }
461                 try {
462                         saveProperties();
463                 } catch (IOException e) {
464                         e.printStackTrace();
465                 }
466                 return messageList;
467         }
468
469         /**
470          * まだ取得していないSendDirectMessageを取得
471          * 
472          * @return
473          * @throws TwitterException
474          */
475         public List<Status> getNewSendDirectMessages() throws TwitterException {
476                 if (this.sinceSendDirectMessageID == 0) {
477                         return getSendDirectMessages(MAX_TWEET_NUM);
478                 }
479                 List<DirectMessage> directMessages = twitter
480                                 .getDirectMessages(new Paging(sinceSendDirectMessageID));
481                 // もし20件データ取得したらもっとデータがある可能性がある
482                 if (directMessages.size() >= 20) {
483                         List<DirectMessage> ndata = twitter
484                                         .getSentDirectMessages(new Paging(1, MAX_TWEET_NUM));
485                         ndata = ndata.subList(21, ndata.size());
486                         for (DirectMessage s : ndata) {
487                                 // すでに取得したことのあるデータだったとき
488                                 if (s.getId() <= sinceSendDirectMessageID) {
489                                         break;
490                                 }
491                                 directMessages.add(s);
492                         }
493                 }
494                 // Tweetの一覧
495                 List<Status> messageList = new LinkedList<Status>();
496                 if (directMessages != null && directMessages.size() > 0) {
497                         // tweetIDを保存しておく
498                         this.sinceSendDirectMessageID = directMessages.get(0).getId();
499                         // 一番新しいtweetを一番したに持ってくる
500                         for (DirectMessage message : directMessages) {
501                                 Status status = message.getRecipient().getStatus();
502                                 messageList.add(0, status);
503                         }
504                 }
505                 try {
506                         saveProperties();
507                 } catch (IOException e) {
508                         e.printStackTrace();
509                 }
510                 return messageList;
511         }
512
513         /**
514          * まだ取得していないMention情報を取得
515          * 
516          * @return
517          * @throws TwitterException
518          */
519         public List<Status> getNewMentionData() throws TwitterException {
520                 // 一度もデータを取得していないとき
521                 if (sinceMentionID == 0) {
522                         return getMentions(MAX_TWEET_NUM);
523                 }
524                 // getFriendsTimelineではRetweetは表示されないので注意
525                 List<Status> statuses = twitter.getMentions(new Paging(sinceMentionID));
526                 // もし20件データ取得したらもっとデータがある可能性がある
527                 if (statuses.size() >= 20) {
528                         List<Status> ndata = twitter.getMentions(new Paging(1,
529                                         MAX_TWEET_NUM));
530                         ndata = ndata.subList(21, ndata.size());
531                         for (Status s : ndata) {
532                                 // すでに取得したことのあるデータだったとき
533                                 if (s.getId() <= sinceMentionID) {
534                                         break;
535                                 }
536                                 statuses.add(s);
537                         }
538                 }
539
540                 // Tweetの一覧
541                 List<Status> tweetList = new LinkedList<Status>();
542                 if (statuses != null && statuses.size() > 0) {
543                         // tweetIDを保存しておく
544                         sinceMentionID = statuses.get(0).getId();
545
546                         // 一番新しいtweetを一番したに持ってくる
547                         for (Status status : statuses) {
548                                 tweetList.add(0, status);
549                         }
550                 }
551                 try {
552                         saveProperties();
553                 } catch (IOException e) {
554                         e.printStackTrace();
555                 }
556                 return tweetList;
557         }
558
559         /**
560          * まだ取得していないtweet情報を取得
561          * 
562          * @return
563          * @throws TwitterException
564          */
565         public List<Status> getNewTimelineData() throws TwitterException {
566                 // 一度もデータを取得していないとき
567                 if (sinceTweetID == 0) {
568                         return getTimeline(MAX_TWEET_NUM);
569                 }
570                 // getFriendsTimelineではRetweetは表示されないので注意
571                 List<Status> statuses = twitter
572                                 .getHomeTimeline(new Paging(sinceTweetID));
573                 // もし20件データ取得したらもっとデータがある可能性がある
574                 if (statuses.size() >= 20) {
575                         List<Status> ndata = twitter.getHomeTimeline(new Paging(1,
576                                         MAX_TWEET_NUM));
577                         ndata = ndata.subList(21, ndata.size());
578                         for (Status s : ndata) {
579                                 // すでに取得したことのあるデータだったとき
580                                 if (s.getId() <= sinceTweetID) {
581                                         break;
582                                 }
583                                 statuses.add(s);
584                         }
585                 }
586                 // Tweetの一覧
587                 List<Status> tweetList = new LinkedList<Status>();
588                 if (statuses != null && statuses.size() > 0) {
589                         // tweetIDを保存しておく
590                         sinceTweetID = statuses.get(0).getId();
591
592                         // 一番新しいtweetを一番したに持ってくる
593                         for (Status status : statuses) {
594                                 tweetList.add(0, status);
595                         }
596                 }
597                 // ログ保存
598                 try {
599                         for (Status s : tweetList) {
600                                 logManager.add(s);
601                         }
602                 } catch (IOException e) {
603                         e.printStackTrace();
604                 }
605                 // 設定ファイル保存
606                 try {
607                         saveProperties();
608                 } catch (IOException e) {
609                         e.printStackTrace();
610                 }
611                 return tweetList;
612         }
613
614         /**
615          * タイムラインを取得 一番新しいツイートは要素の一番下に追加
616          * 
617          * @param num
618          *            指定した数だけtweetを取得
619          * @return
620          * @throws TwitterException
621          */
622         public List<Status> getTimeline(int num) throws TwitterException {
623                 // getFriendsTimelineではRetweetは表示されないので注意
624                 List<Status> statuses = twitter.getHomeTimeline(new Paging(1, num));
625                 // Tweetの一覧
626                 List<Status> tweetList = new LinkedList<Status>();
627                 if (statuses != null && statuses.size() > 0) {
628                         // tweetIDを保存しておく
629                         sinceTweetID = statuses.get(0).getId();
630
631                         // 一番新しいtweetを一番したに持ってくる
632                         for (Status status : statuses) {
633                                 tweetList.add(0, status);
634                         }
635                 }
636                 // ログ保存
637                 try {
638                         for (Status s : tweetList) {
639                                 logManager.add(s);
640                         }
641                 } catch (IOException e) {
642                         e.printStackTrace();
643                 }
644                 try {
645                         saveProperties();
646                 } catch (IOException e) {
647                         e.printStackTrace();
648                 }
649                 return tweetList;
650         }
651
652         /**
653          * 指定したワードを含むtweetを返す
654          * 
655          * @param sinceID
656          * @param searchWord
657          * @return
658          */
659         public List<Status> getNewSearchResult(long sinceID, String searchWord) {
660                 // 一度もデータを取得していないとき
661                 if (sinceID == 0) {
662                         return getSearchResult(MAX_TWEET_NUM, searchWord);
663                 }
664
665                 // TODO:同じようなコードを二回書いてる.ここは修正の必要があるかも
666
667                 Query query = new Query(searchWord);
668                 // 取得するツイート最大数
669                 query.setRpp(this.MAX_TWEET_NUM);
670                 // 取得するページ番号
671                 query.setPage(1);
672                 // 追加: sinceIDを登録
673                 query.setSinceId(sinceID);
674                 // 検索結果
675                 QueryResult queryResult = null;
676                 try {
677                         queryResult = twitter.search(query);
678                 } catch (TwitterException ex) {
679                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
680                                         "Twitter searchに失敗しました", ex);
681                         ex.printStackTrace();
682                 }
683
684                 List<Status> tweetList = new LinkedList<Status>();
685
686                 if (queryResult != null) {
687                         for (Tweet tweet : queryResult.getTweets()) {
688                                 // 取得できる最大限の情報を返す
689                                 SimpleUser user = new SimpleUser();
690                                 // ユーザ名
691                                 user.setName(tweet.getFromUser());
692                                 user.setScreenName(tweet.getFromUser());
693                                 // ユーザID
694                                 user.setId(tweet.getFromUserId());
695                                 try {
696                                         // ユーザイメージ
697                                         user
698                                                         .setProfileImageURL(new URL(tweet
699                                                                         .getProfileImageUrl()));
700                                 } catch (MalformedURLException ex) {
701                                         Logger.getLogger(TweetManager.class.getName()).log(
702                                                         Level.SEVERE, null, ex);
703                                 }
704
705                                 SimpleStatus status = new SimpleStatus();
706                                 status.setCreatedAt(tweet.getCreatedAt());
707                                 status.setId(tweet.getId());
708                                 status.setSource(tweet.getSource());
709                                 status.setText(tweet.getText());
710                                 status.setUser(user);
711
712                                 // 情報追加
713                                 tweetList.add(status);
714                         }
715                 }
716                 // リスト逆転 一番あたらしいtweetを一番下に
717                 Collections.reverse(tweetList);
718
719                 return tweetList;
720         }
721
722         /**
723          * 指定したワードを含むtweetを返す
724          * 
725          * @param num
726          *            指定した数だけtweetを取得
727          * @param searchWord
728          *            検索したい単語
729          * @return
730          */
731         public List<Status> getSearchResult(int num, String searchWord) {
732                 Query query = new Query(searchWord);
733                 // 取得するツイート最大数
734                 query.setRpp(num);
735                 // 取得するページ番号
736                 query.setPage(1);
737                 // 検索結果
738                 QueryResult queryResult = null;
739                 try {
740                         queryResult = twitter.search(query);
741                 } catch (TwitterException ex) {
742                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
743                                         "Twitter searchに失敗しました", ex);
744                         ex.printStackTrace();
745                 }
746
747                 List<Status> tweetList = new LinkedList<Status>();
748
749                 if (queryResult != null) {
750                         for (Tweet tweet : queryResult.getTweets()) {
751                                 // 取得できる最大限の情報を返す
752                                 SimpleUser user = new SimpleUser();
753                                 // ユーザ名
754                                 user.setName(tweet.getFromUser());
755                                 user.setScreenName(tweet.getFromUser());
756                                 // ユーザID
757                                 user.setId(tweet.getFromUserId());
758                                 try {
759                                         // ユーザイメージ
760                                         user
761                                                         .setProfileImageURL(new URL(tweet
762                                                                         .getProfileImageUrl()));
763                                 } catch (MalformedURLException ex) {
764                                         Logger.getLogger(TweetManager.class.getName()).log(
765                                                         Level.SEVERE, null, ex);
766                                 }
767
768                                 SimpleStatus status = new SimpleStatus();
769                                 status.setCreatedAt(tweet.getCreatedAt());
770                                 status.setId(tweet.getId());
771                                 status.setSource(tweet.getSource());
772                                 status.setText(tweet.getText());
773                                 status.setUser(user);
774
775                                 // 情報追加
776                                 tweetList.add(status);
777                         }
778                 }
779
780                 // リスト逆転 一番あたらしいtweetを一番下に
781                 Collections.reverse(tweetList);
782
783                 return tweetList;
784         }
785
786         /**
787          * 指定したユーザのお気に入りを取得
788          * 
789          * @param screenName
790          *            nullの場合,自分自身のお気に入りを取得
791          */
792         public List<Status> getFavoritesTweet(String screenName)
793                         throws TwitterException {
794                 // getFriendsTimelineではRetweetは表示されないので注意
795                 List<Status> statuses = null;
796                 if (screenName == null) {
797                         // 自分自身のお気に入り取得
798                         statuses = twitter.getFavorites();
799                 } else {
800                         statuses = twitter.getFavorites(screenName);
801                 }
802                 // リスト逆転 一番あたらしいtweetを一番下に
803                 Collections.reverse(statuses);
804                 return statuses;
805         }
806
807         /**
808          * 指定したユーザの発言を取得
809          * 
810          * @param num
811          * @param userID
812          * @return
813          * @throws TwitterException
814          */
815         public List<Status> getUserTimeline(int num, long userID)
816                         throws TwitterException {
817                 List<Status> statuses = twitter.getUserTimeline(userID, new Paging(1,
818                                 num));
819
820                 // tweet逆転
821                 if (statuses != null && statuses.size() > 0) {
822                         Collections.reverse(statuses);
823                 }
824
825                 return statuses;
826         }
827
828         /**
829          * 指定したユーザが保持しているリスト一覧を取得
830          * 
831          * @param userScreenName
832          * @return
833          */
834         public List<UserList> getUserLists(String userScreenName) {
835                 List<UserList> userlist = new ArrayList<UserList>();
836                 long cursor = -1;
837                 try {
838                         for (;;) {
839                                 // ユーザリスト取得
840                                 PagableResponseList<UserList> list = this.twitter.getUserLists(
841                                                 userScreenName, cursor);
842                                 userlist.addAll(list);
843
844                                 if (list.hasNext()) {
845                                         // 次のカーソルを取得
846                                         cursor = list.getNextCursor();
847                                 } else {
848                                         break;
849                                 }
850                         }
851                 } catch (TwitterException ex) {
852                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
853                                         null, ex);
854                 }
855                 return userlist;
856         }
857
858         /**
859          * 指定したユーザをフォローしているリストを返す
860          * 
861          * @param userScreenName
862          * @return
863          */
864         public List<UserList> getUserListSubscriptions(String userScreenName) {
865                 List<UserList> userlist = new ArrayList<UserList>();
866                 long cursor = -1;
867                 try {
868                         for (;;) {
869                                 // ユーザリスト取得
870                                 PagableResponseList<UserList> list = this.twitter
871                                                 .getUserListSubscriptions(userScreenName, cursor);
872                                 userlist.addAll(list);
873
874                                 if (list.hasNext()) {
875                                         // 次のカーソルを取得
876                                         cursor = list.getNextCursor();
877                                 } else {
878                                         break;
879                                 }
880                         }
881                 } catch (TwitterException ex) {
882                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
883                                         null, ex);
884                 }
885                 return userlist;
886         }
887
888         /**
889          * 指定したユーザが追加されているリストを返す
890          * 
891          * @param userScreenName
892          * @return
893          */
894         public List<UserList> getUserListMemberships(String userScreenName) {
895                 List<UserList> userlist = new ArrayList<UserList>();
896                 long cursor = -1;
897                 try {
898                         for (;;) {
899                                 // ユーザリスト取得
900                                 PagableResponseList<UserList> list = this.twitter
901                                                 .getUserListMemberships(userScreenName, cursor);
902                                 userlist.addAll(list);
903
904                                 if (list.hasNext()) {
905                                         // 次のカーソルを取得
906                                         cursor = list.getNextCursor();
907                                 } else {
908                                         break;
909                                 }
910                         }
911                 } catch (TwitterException ex) {
912                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
913                                         null, ex);
914                 }
915                 return userlist;
916         }
917
918         /**
919          * 指定したリストのツイートを取得
920          * 
921          * @param userScreenName
922          *            ユーザ名
923          * @param listID
924          *            リストID
925          * @param num
926          *            取得ツイート数
927          * @return
928          * @throws TwitterException
929          */
930         public List<Status> getUserListStatuses(String userScreenName, int listID,
931                         int num) {
932                 List<Status> tweetList = null;
933                 try {
934                         tweetList = this.twitter.getUserListStatuses(userScreenName,
935                                         listID, new Paging(1, num));
936                 } catch (TwitterException ex) {
937                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
938                                         null, ex);
939                 }
940                 // tweet逆転
941                 if (tweetList != null && tweetList.size() > 0) {
942                         Collections.reverse(tweetList);
943                 }
944                 return tweetList;
945         }
946
947         /**
948          * 指定したリストの最新情報を取得
949          * 
950          * @param userScreenName
951          *            ユーザ名
952          * @param listID
953          *            リストID
954          * @param sinceID
955          * @return
956          */
957         public List<Status> getNewUserListStatuses(String userScreenName,
958                         int listID, long sinceID) {
959                 if (sinceID == 0) {
960                         return getUserListStatuses(userScreenName, listID, MAX_TWEET_NUM);
961                 }
962                 List<Status> tweetList = null;
963                 try {
964                         tweetList = this.twitter.getUserListStatuses(userScreenName,
965                                         listID, new Paging(sinceID));
966                 } catch (TwitterException ex) {
967                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
968                                         null, ex);
969                 }
970                 // tweet逆転
971                 if (tweetList != null && tweetList.size() > 0) {
972                         Collections.reverse(tweetList);
973                 }
974                 return tweetList;
975         }
976
977         /**
978          * 指定したユーザの最新の発言を取得
979          * 
980          * @param userID
981          * @param sinceID
982          * @return
983          * @throws TwitterException
984          */
985         public List<Status> getNewUserTimeline(long userID, long sinceID)
986                         throws TwitterException {
987                 // 一度もデータを取得していないとき
988                 if (sinceID == 0) {
989                         return getUserTimeline(MAX_TWEET_NUM, userID);
990                 }
991
992                 List<Status> statuses = twitter.getUserTimeline(userID, new Paging(
993                                 sinceID));
994
995                 // tweet逆転
996                 if (statuses != null && statuses.size() > 0) {
997                         Collections.reverse(statuses);
998                 }
999
1000                 return statuses;
1001         }
1002
1003         /**
1004          * Twitterへログイン
1005          */
1006         public void loginTwitter() throws FileNotFoundException, IOException {
1007                 twitter = new TwitterFactory().getInstance();
1008                 // アカウント情報を読み込む
1009                 loadAccountProperties();
1010                 // ConsumerKeyなどを設定
1011                 twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
1012                 // ここにユーザのアクセストークンを入れる
1013                 AccessToken ac = new AccessToken(accessToken, secretToken);
1014                 twitter.setOAuthAccessToken(ac);
1015                 // 設定ファイルを読み込む
1016                 try {
1017                         loadProperties();
1018                 } catch (FileNotFoundException e) {
1019                         e.printStackTrace();
1020                 } catch (IOException e) {
1021                         e.printStackTrace();
1022                 }
1023         }
1024
1025         /**
1026          * Configurationを生成する
1027          * 
1028          * @return
1029          */
1030         private Configuration getTwitterConfiguration() {
1031                 ConfigurationBuilder confbuilder = new ConfigurationBuilder();
1032                 confbuilder.setOAuthConsumerKey(CONSUMER_KEY);
1033                 confbuilder.setOAuthConsumerSecret(CONSUMER_SECRET);
1034                 return confbuilder.build();
1035         }
1036
1037         /**
1038          * 初回時アクセストークンを取得する際に利用する
1039          * 
1040          * @param username
1041          * @param password
1042          * @throws TwitterException
1043          */
1044         public void getAccessToken(String username, String password)
1045                         throws TwitterException {
1046                 // consumer key secretを設定
1047                 Configuration conf = this.getTwitterConfiguration();
1048                 twitter = new TwitterFactory(conf).getInstance();
1049                 // access token取得
1050                 AccessToken oAuthAccessToken = twitter.getOAuthAccessToken(username, password);
1051                 this.accessToken = oAuthAccessToken.getToken();
1052                 this.secretToken = oAuthAccessToken.getTokenSecret();
1053
1054                 try {
1055                         // 取得したOAuthのトークンを保存
1056                         saveAccountProperties();
1057                 } catch (IOException ex) {
1058                         ex.printStackTrace();
1059                 }
1060         }
1061
1062         /**
1063          * メッセージをつぶやく
1064          * 
1065          * @param message
1066          */
1067         public void tweet(String message) {
1068                 twitter4j.Status status;
1069                 try {
1070                         status = twitter.updateStatus(message);
1071                 } catch (TwitterException e) {
1072                         // TODO: エラー処理
1073                         e.printStackTrace();
1074                 }
1075         }
1076
1077         /**
1078          * 返信メッセージをつぶやく
1079          * 
1080          * @param message
1081          * @param replyToStatusID
1082          */
1083         public void replyTweet(String message, long replyToStatusID) {
1084                 twitter4j.Status status;
1085                 try {
1086                         // status = twitter.updateStatus(message, replyToStatusID);
1087                         StatusUpdate updateMsg = new StatusUpdate(message);
1088                         updateMsg.setInReplyToStatusId(replyToStatusID);
1089                         status = twitter.updateStatus( updateMsg );
1090                 } catch (TwitterException e) {
1091                         // TODO: エラー処理
1092                         e.printStackTrace();
1093                 }
1094         }
1095
1096         /**
1097          * ダイレクトメッセージを送信
1098          * 
1099          * @param screenName
1100          * @param text
1101          * @throws TwitterException
1102          */
1103         public void sendDirectMessage(String screenName, String text)
1104                         throws TwitterException {
1105                 twitter.sendDirectMessage(screenName, text);
1106         }
1107
1108         /**
1109          * 指定したステータスIDの発言をRetweet
1110          * 
1111          * @param statusID
1112          * @throws TwitterException
1113          */
1114         public void retweet(long statusID) throws TwitterException {
1115                 twitter.retweetStatus(statusID);
1116         }
1117
1118         /**
1119          * 指定した発言をお気に入りに追加
1120          * 
1121          * @param statusID
1122          * @throws TwitterException
1123          */
1124         public void createFavorite(long statusID) throws TwitterException {
1125                 twitter.createFavorite(statusID);
1126         }
1127
1128         /**
1129          * 指定した発言のお気に入りを取り下げる
1130          * 
1131          * @param statusID
1132          */
1133         public void destroyFavorite(long statusID) throws TwitterException {
1134                 twitter.destroyFavorite(statusID);
1135         }
1136
1137         /**
1138          * API制限数を取得
1139          * 
1140          * @return
1141          * @throws TwitterException
1142          */
1143         public RateLimitStatus getRateLimitStatus() throws TwitterException {
1144                 return twitter.getRateLimitStatus();
1145         }
1146
1147         /**
1148          * 自分自身のスクリーン名を返す
1149          * 
1150          * @return
1151          */
1152         public String getScreenName() {
1153                 try {
1154                         if (twitter != null) {
1155                                 return twitter.getScreenName();
1156                         }
1157                 } catch (TwitterException e) {
1158
1159                 }
1160                 return null;
1161         }
1162 }