C++ wrapper for the Mastodon API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

example03_mastocron.cpp 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* This file is part of mastodon-cpp.
  2. * Prints the new toots under a hashtag, designed to be used in cronjobs
  3. */
  4. #include <iostream>
  5. #include <vector>
  6. #include <string>
  7. #include <cstdint>
  8. #include <regex>
  9. #include <cstdlib>
  10. #include <fstream>
  11. #include <sstream>
  12. #include <jsoncpp/json/json.h>
  13. #ifdef MASTODON_CPP
  14. #include "mastodon-cpp.hpp"
  15. #else
  16. #include <mastodon-cpp/mastodon-cpp.hpp>
  17. #endif
  18. using Mastodon::API;
  19. using std::cout;
  20. using std::string;
  21. int main(int argc, char *argv[])
  22. {
  23. string limit = "20";
  24. if (argc < 3)
  25. {
  26. std::cerr << "usage: " << argv[0] << " <instance> <hashtag> [limit]\n";
  27. std::cerr << " Default limit is 20, max limit is 40.\n";
  28. return 1;
  29. }
  30. else if (argc == 4)
  31. {
  32. limit = argv[3];
  33. }
  34. Mastodon::API masto(argv[1], "");
  35. string hashtag = argv[2];
  36. string answer;
  37. std::stringstream ss;
  38. std::uint16_t ret;
  39. Json::Value config;
  40. string lastid = "0";
  41. string filename = string(getenv("HOME")) + "/.config/mastocron.json";
  42. // Read config file, get last seen toot-id
  43. try {
  44. std::ifstream file(filename, std::ifstream::binary);
  45. file >> config;
  46. lastid = config.get(hashtag, "0").asString();
  47. }
  48. catch (std::exception &e)
  49. {
  50. // most likely no config file found, ignore
  51. }
  52. // Only get toots we haven't seen yet
  53. API::parametermap params =
  54. {
  55. { "hashtag", { hashtag } },
  56. { "limit", { limit } },
  57. { "since_id", { lastid } }
  58. };
  59. ret = masto.get(API::v1::timelines_tag_hashtag, params, answer);
  60. if (ret == 0)
  61. {
  62. // If answer is empty, there are no new toots,
  63. // if answer is "[]" there are none at all
  64. if (answer != "" && answer != "[]")
  65. {
  66. string ornament = " +++++";
  67. for (std::uint8_t i = hashtag.size(); i > 0; --i)
  68. {
  69. ornament += "+";
  70. }
  71. cout << ornament << '\n';
  72. cout << " + " << hashtag << ": +\n";
  73. cout << ornament << '\n';
  74. Json::Value tree;
  75. ss.str(answer);
  76. ss >> tree;
  77. for (const auto &toot : tree)
  78. {
  79. string content = toot["content"].asString();
  80. std::regex reparagraph("</p><p>");
  81. std::regex restrip("<[^>]*>");
  82. cout << "++++++++\n";
  83. content = std::regex_replace(content, reparagraph, "\n\n");
  84. cout << std::regex_replace(content, restrip, "") << '\n';
  85. cout << " – ";
  86. cout << toot["account"]["display_name"].asString()
  87. << " (" << toot["account"]["acct"] << ") at "
  88. << toot["created_at"].asString() << "\n";
  89. cout << " " << toot["url"].asString() << '\n';
  90. for (const auto &media : toot["media_attachments"])
  91. {
  92. cout << "Attachment: <" << media["url"].asString() << ">\n";
  93. }
  94. cout << "++++++++\n";
  95. }
  96. // Write the id of the newest toot in the config file
  97. lastid = tree[0]["id"].asString();
  98. config[hashtag] = lastid;
  99. Json::StreamWriterBuilder wbuilder;
  100. const string output = Json::writeString(wbuilder, config);
  101. std::ofstream outfile(filename);
  102. if (outfile.is_open())
  103. {
  104. outfile.write(output.c_str(), output.length());
  105. outfile.close();
  106. }
  107. }
  108. }
  109. else if (ret == 13)
  110. {
  111. std::cerr << "The URL has permanently changed.\n" <<
  112. "New URL: " << answer << '\n';
  113. return ret;
  114. }
  115. else
  116. {
  117. std::cerr << "Error code: " << ret << '\n';
  118. return ret;
  119. }
  120. return 0;
  121. }