Package nl.topicus.onderwijs.dashboard.modules.twitter

Source Code of nl.topicus.onderwijs.dashboard.modules.twitter.TwitterService

package nl.topicus.onderwijs.dashboard.modules.twitter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;

import nl.topicus.onderwijs.dashboard.config.ISettings;
import nl.topicus.onderwijs.dashboard.datasources.TwitterMentions;
import nl.topicus.onderwijs.dashboard.datasources.TwitterTimeline;
import nl.topicus.onderwijs.dashboard.datatypes.TwitterStatus;
import nl.topicus.onderwijs.dashboard.keys.Key;
import nl.topicus.onderwijs.dashboard.modules.AbstractService;
import nl.topicus.onderwijs.dashboard.modules.DashboardRepository;
import nl.topicus.onderwijs.dashboard.modules.ServiceConfiguration;
import nl.topicus.onderwijs.dashboard.modules.twitter.TwitterSettings.OAuthKey;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import twitter4j.RateLimitStatus;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.Authorization;
import twitter4j.auth.AuthorizationFactory;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;

@Service
@ServiceConfiguration(interval = 1, unit = TimeUnit.MINUTES)
public class TwitterService extends AbstractService {
  private static final Logger logger = LoggerFactory
      .getLogger(TwitterService.class);
  private Map<Key, List<Twitter>> twitters = new HashMap<Key, List<Twitter>>();

  private Map<Key, NavigableSet<Status>> timeline = new HashMap<Key, NavigableSet<Status>>();
  private Map<Key, NavigableSet<Status>> mentions = new HashMap<Key, NavigableSet<Status>>();

  @Autowired
  public TwitterService(ISettings settings) {
    super(settings);
  }

  public void onConfigure(DashboardRepository repository) {
    for (Entry<Key, Map<String, ?>> settingsEntry : getSettings()
        .getServiceSettings(TwitterService.class).entrySet()) {
      Key key = settingsEntry.getKey();

      TwitterSettings settings = new TwitterSettings(
          settingsEntry.getValue());

      String oAuthConsumerKey = settings.getApplicationKey().getKey();
      String oAuthConsumerSecret = settings.getApplicationKey()
          .getSecret();

      List<Twitter> keyTwitters = new ArrayList<Twitter>();
      for (Entry<String, OAuthKey> tokenEntry : settings.getTokens()
          .entrySet()) {

        OAuthKey token = tokenEntry.getValue();

        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.setOAuthConsumerKey(oAuthConsumerKey);
        builder.setOAuthConsumerSecret(oAuthConsumerSecret);
        builder.setOAuthAccessToken(token.getKey());
        builder.setOAuthAccessTokenSecret(token.getSecret());
        Configuration conf = builder.build();

        Authorization authorization = AuthorizationFactory
            .getInstance(conf);
        Twitter twitter = new TwitterFactory()
            .getInstance(authorization);
        keyTwitters.add(twitter);
      }
      twitters.put(key, keyTwitters);
      mentions.put(key, new TreeSet<Status>());
      timeline.put(key, new TreeSet<Status>());
      repository.addDataSource(key, TwitterTimeline.class,
          new TwitterTimelineImpl(key, this));
      repository.addDataSource(key, TwitterMentions.class,
          new TwitterMentionsImpl(key, this));
    }
  }

  @Override
  public void refreshData() {
    for (Entry<Key, List<Twitter>> twitterEntry : twitters.entrySet()) {
      for (Twitter twitter : twitterEntry.getValue()) {
        pullTweets(twitterEntry.getKey(), twitter);
      }
    }
  }

  private void pullTweets(Key key, Twitter twitter) {
    try {
      RateLimitStatus rateLimitStatus = twitter.getRateLimitStatus();
      if (rateLimitStatus.getRemainingHits() == 0)
        return;

      double currentRate = (rateLimitStatus.getHourlyLimit() - rateLimitStatus
          .getRemainingHits())
          / (3601 - rateLimitStatus.getSecondsUntilReset());
      logger.info(
          "Current twitter refresh rate: {}/h, official refresh rate: {}",
          String.format("%1.1f", currentRate),
          rateLimitStatus.getHourlyLimit());
      if (currentRate > rateLimitStatus.getHourlyLimit()) {
        logger.info("Skipped refreshing Twitter feeds to limit the refresh rate");
        return;
      }

      ResponseList<Status> newFriendsTimeline = twitter.getHomeTimeline();
      ResponseList<Status> newMentions = twitter.getMentions();
      synchronized (this) {
        mergeStatuses(timeline.get(key), newFriendsTimeline);
        mergeStatuses(mentions.get(key), newMentions);
      }
    } catch (TwitterException e) {
      logger.warn("Twitter reported an error: " + e.getMessage(), e);
    }
  }

  private void mergeStatuses(NavigableSet<Status> originalStatuses,
      List<Status> newStatuses) {
    originalStatuses.addAll(newStatuses);

    while (originalStatuses.size() >= 40) {
      originalStatuses.pollFirst();
    }
  }

  public synchronized List<TwitterStatus> getTimeline(Key key) {
    List<TwitterStatus> ret = new ArrayList<TwitterStatus>();
    for (Status curStatus : timeline.get(key)) {
      ret.add(new TwitterStatus(key, curStatus));
    }
    Collections.reverse(ret);
    return ret;
  }

  public synchronized List<TwitterStatus> getMentions(Key key) {
    List<TwitterStatus> ret = new ArrayList<TwitterStatus>();
    for (Status curStatus : mentions.get(key)) {
      ret.add(new TwitterStatus(key, curStatus));
    }
    Collections.reverse(ret);
    return ret;
  }
}
TOP

Related Classes of nl.topicus.onderwijs.dashboard.modules.twitter.TwitterService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.