stackexchange_通过Spring Social发推StackExchange问​​题

甄鹏云
2023-12-01

stackexchange

1.简介

这是有关小型辅助项目的第三篇也是最后一篇文章-该机器人自动在专用帐户上发布来自各个Q&A StackExchange网站上的问题的推文(文章末尾的完整列表)。

第一篇文章讨论了为StackExchange REST API构建简单的客户端 。 在第二篇文章中,我们使用Spring Social建立了与Twitter的交互。

本文将描述实现的最后一部分-负责Stackexchange客户端与TwitterTemplate之间的交互的部分。

2. Tweet Stackexchange服务

Stackexchange客户端(暴露原始问题)与TwitterTemplate (完全设置并可以鸣叫)之间的交互是一个非常简单的服务,即TweetStackexchangeService 。 由此发布的API是:

public void tweetTopQuestionBySite(String site, String twitterAccount){ ... }
public void tweetTopQuestionBySiteAndTag(String site, String twitterAccount, String tag){ ... }

功能很简单–这些API将继续(通过客户端)从Stackexchange REST API中读取“问题”,直到在该特定帐户上发现之前从未发布过任何Twitter消息为止。

找到该问题后,将通过与该帐户相对应TwitterTemplateTwitter上发布该消息,并将一个非常简单的Question实体保存在本地。 该实体仅存储问题的ID和发过该消息的Twitter帐户。

例如以下问题: 在@RequestParam中绑定列表 SpringAtSO帐户上发布。

Question实体仅包含:

  • 问题的编号 –在这种情况下为4596351
  • 问题已在其上发布的Twitter帐户 – SpringAtSO
  • 问题源自的Stackexcange网站 – stackoverflow

我们需要跟踪此信息,以便我们知道哪些问题已被发布,哪些问题尚未被发布。

3.调度程序

调度程序利用了Spring的调度任务功能-通过Java配置启用了这些功能:

@Configuration
@EnableScheduling
public class ContextConfig {
   //
}

实际的调度程序相对简单:

@Component
@Profile(SpringProfileUtil.DEPLOYED)
public class TweetStackexchangeScheduler {

   @Autowired
   private TweetStackexchangeService service;

   // API

   @Scheduled(cron = "0 0 1,5 * * *")
   public void tweetStackExchangeTopQuestion() throws JsonProcessingException, IOException {
      service.tweetTopQuestionBySiteAndTag("StackOverflow", Tag.clojure.name(), "BestClojure", 1);
      String randomSite = StackexchangeUtil.pickOne("SuperUser", "StackOverflow");
      service.tweetTopQuestionBySiteAndTag(randomSite, Tag.bash.name(), "BestBash", 1);
   }
}

上面配置了两个推文操作–来自StackOverflow问题的一个推文,在Best Of Clojure Twitter帐户上标有“ clojure”。

其他操作将推文标记为“ bash”的问题–由于这类问题实际上出现在Stackexchange网络上的多个站点上: StackOverflowSuperUserAskUbuntu ,因此首先有一个快速选择过程来选择这些站点之一,然后问题已发布。

最后, 计划cron作业每天在凌晨1点和凌晨5点运行

4.设定

这是一个宠物项目,它以非常简单的数据库结构开始 -现在仍然很简单,但情况更是如此。 因此,主要目标之一是能够轻松更改数据库结构-当然,有几种用于数据库迁移的工具 ,但是对于这样一个简单的项目,它们都是过大的。

因此,我决定将设置数据保留为简单的文本格式 -将以半自动方式进行更新。

安装程序有两个主要步骤:

  • 检索每个Twitter帐户上的推文问题的ID,并将其存储在文本文件中
  • 删除数据库架构并重新启动应用程序–这将再次创建架构,并将所有数据从文本文件设置回新数据库

4.1。 原始设置数据

使用JDBC检索现有数据库中的数据的过程非常简单; 首先我们定义一个RowMapper:

class TweetRowMapper implements RowMapper<String> {
   private Map<String, List<Long>> accountToQuestions;

   public TweetRowMapper(Map<String, List<Long>> accountToQuestions) {
      super();
      this.accountToQuestions = accountToQuestions;
   }

   public String mapRow(ResultSet rs, int line) throws SQLException {
      String questionIdAsString = rs.getString("question_id");
      long questionId = Long.parseLong(questionIdAsString);
      String account = rs.getString("account");

      if (accountToQuestions.get(account) == null) {
         accountToQuestions.put(account, Lists.<Long> newArrayList());
      }
      accountToQuestions.get(account).add(questionId);
      return "";
   }
}

这将为每个Twitter帐户建立一个问题列表。

接下来,我们将在一个简单的测试中使用它:

@Test
public void whenQuestionsAreRetrievedFromTheDB_thenNoExceptions() {
   Map<String, List<Long>> accountToQuestionsMap = Maps.newHashMap();
   jdbcTemplate.query
      ("SELECT * FROM question_tweet;", new TweetRowMapper(accountToQuestionsMap));

   for (String accountName : accountToQuestionsMap.keySet()) {
      System.out.println
         (accountName + "=" + valuesAsCsv(accountToQuestionsMap.get(accountName)));
   }
}

检索帐户问题后,测试将简单地列出问题; 例如:

SpringAtSO=3652090,1079114,5908466,...

4.2。 恢复设置数据

上一步生成的数据行存储在setup.properties文件中 ,该文件可用于Spring:

@Configuration
@PropertySource({ "classpath:setup.properties" })
public class PersistenceJPAConfig {
   //
}

当应用程序启动时,将执行设置过程。 这个简单的过程使用Spring ApplicationListener,监听ContextRefreshedEvent

@Component
public class StackexchangeSetup implements ApplicationListener<ContextRefreshedEvent> {
    private boolean setupDone;

    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (!setupDone) {
            recreateAllQuestionsOnAllTwitterAccounts();
            setupDone = true;
        }
    }
}

最后,从setup.properties文件中检索问题并重新创建:

private void recreateAllQuestionsOnTwitterAccount(String twitterAccount) {
   String tweetedQuestions = env.getProperty(twitterAccount.name();
   String[] questionIds = tweetedQuestions.split(",");
   recreateQuestions(questionIds, twitterAccount);
}
void recreateQuestions(String[] questionIds, String twitterAccount) {
   List<String> stackSitesForTwitterAccount = twitterAccountToStackSites(twitterAccount);
   String site = stackSitesForTwitterAccount.get(0);
   for (String questionId : questionIds) {
      QuestionTweet questionTweet = new QuestionTweet(questionId, twitterAccount, site);
      questionTweetDao.save(questionTweet);
   }
}

这个简单的过程可以轻松地更新数据库结构-由于完全擦除了数据并完全重新创建了数据,因此无需进行任何实际的迁移

5.帐户完整清单

Twitter帐户完整列表是:

  • SpringAtSO –来自StackOverflow的Spring问题
  • JavaTopSO –来自StackOverflow的Java问题
  • RESTDaily –来自StackOverflow的REST问题
  • BestJPA –来自StackOverflow的JPA问题
  • BestMaven –来自StackOverflow的Maven问题
  • BestGit –来自StackOverflow的Git问题
  • AskUbuntuBestAskUbuntu最佳总体问题(所有主题)
  • ServerFaultBestServerFault最佳问题(所有主题)
  • BestBash –来自StackOverflow,ServerFault和AskUbuntu的最佳Bash问题
  • BestClojure –来自StackOverflow的Clojure问题
  • BestScala –来自StackOverflow的Scala问题
  • BestEclipse –来自StackOverflow的Eclipse问题
  • jQueryDaily –来自StackOverflow的jQuery问题
  • BestAlgorithms –来自StackOverflow的算法问题

这些帐户中的每个帐户每天都会创建2条推文,其特定主题的问题评分最高。

六,结论

第三篇文章完成了与StackOverflow和其他StackExchange站点集成以通过其REST API检索问题,以及与Twitter和Spring Social集成以发布这些问题的系列。 可能值得探索的潜在方向与Google Plus相同(可能使用Pages,而不是帐户)。

14这个项目的结果是Twitter帐户已经建立并开始运行-专注于各种主题,并产生少量且希望高质量的内容(在评论中欢迎其他标记自己Twitter帐户的标记的想法)。

参考:baeldung博客上,我们的JCG合作伙伴 Eugen Paraschiv 与Spring Social一起发布了StackExchange Questions

翻译自: https://www.javacodegeeks.com/2013/05/tweeting-stackexchange-questions-with-spring-social.html

stackexchange

 类似资料: