Write mentions to file
This commit is contained in:
parent
2e2c3fa5b6
commit
59ff7f8821
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required (VERSION 3.7)
|
cmake_minimum_required (VERSION 3.7)
|
||||||
project (mastobotmon
|
project (mastobotmon
|
||||||
VERSION 0.1.4
|
VERSION 0.2.0
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
26
README.md
26
README.md
|
@ -7,7 +7,7 @@
|
||||||
* Tested OS: Linux
|
* Tested OS: Linux
|
||||||
* C++ compiler (tested: gcc 6.4, clang 5.0)
|
* C++ compiler (tested: gcc 6.4, clang 5.0)
|
||||||
* [cmake](https://cmake.org/) (tested: 3.9.6)
|
* [cmake](https://cmake.org/) (tested: 3.9.6)
|
||||||
* [mastodon-cpp](https://github.com/tastytea/mastodon-cpp) (at least: 0.4.4)
|
* [mastodon-cpp](https://github.com/tastytea/mastodon-cpp) (at least: 0.6.0)
|
||||||
* [jsoncpp](https://github.com/open-source-parsers/jsoncpp) (tested: 1.8.1)
|
* [jsoncpp](https://github.com/open-source-parsers/jsoncpp) (tested: 1.8.1)
|
||||||
|
|
||||||
## Get sourcecode
|
## Get sourcecode
|
||||||
|
@ -48,6 +48,28 @@ Same as [mastodon-cpp](https://github.com/tastytea/mastodon-cpp/blob/master/READ
|
||||||
|
|
||||||
If you use a debug build, you get more verbose error messages.
|
If you use a debug build, you get more verbose error messages.
|
||||||
|
|
||||||
|
## Example config file
|
||||||
|
|
||||||
|
{
|
||||||
|
"accounts" : {
|
||||||
|
"account1@example.social" : {
|
||||||
|
"access_token" : "xxxx",
|
||||||
|
"minutes" : 720
|
||||||
|
},
|
||||||
|
"account2@example.social" : {
|
||||||
|
"access_token" : "yyyy",
|
||||||
|
"minutes" : 1450
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"daemon_check" : 10,
|
||||||
|
"data_dir" : "/home/user/mastobotmon",
|
||||||
|
"mode" : "cron"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Mentions
|
||||||
|
|
||||||
|
Mentions are written to `data_dir/mentions_account.csv`. The format is: acct;created_at;content.
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
* Version 0.1.0
|
* Version 0.1.0
|
||||||
|
@ -56,7 +78,7 @@ If you use a debug build, you get more verbose error messages.
|
||||||
* [x] Alert if account seems inactive
|
* [x] Alert if account seems inactive
|
||||||
* Version 0.2.0
|
* Version 0.2.0
|
||||||
* [x] Allow to add accounts later
|
* [x] Allow to add accounts later
|
||||||
* [ ] Write mentions to file
|
* [x] Write mentions to file
|
||||||
* Version 0.3.0
|
* Version 0.3.0
|
||||||
* [ ] Respect X-RateLimit header
|
* [ ] Respect X-RateLimit header
|
||||||
* [ ] Write statistics to file
|
* [ ] Write statistics to file
|
||||||
|
|
|
@ -67,6 +67,12 @@ const bool read_config(Json::Value &document)
|
||||||
cerr << "ERROR: \"daemon_check\" not found\n";
|
cerr << "ERROR: \"daemon_check\" not found\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!document["data_dir"].isString())
|
||||||
|
{
|
||||||
|
cerr << "ERROR: \"data_dir\" not found\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -76,6 +82,7 @@ const bool read_config(Json::Value &document)
|
||||||
|
|
||||||
document["mode"] = "cron";
|
document["mode"] = "cron";
|
||||||
document["daemon_check"] = 10;
|
document["daemon_check"] = 10;
|
||||||
|
document["data_dir"] = ".";
|
||||||
|
|
||||||
return write_config(document);
|
return write_config(document);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip> // get_time
|
#include <iomanip> // get_time
|
||||||
|
#include <fstream>
|
||||||
|
#include <regex>
|
||||||
#include <jsoncpp/json/json.h>
|
#include <jsoncpp/json/json.h>
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "mastobotmon.hpp"
|
#include "mastobotmon.hpp"
|
||||||
|
@ -33,9 +35,37 @@ using std::cin;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::uint16_t;
|
using std::uint16_t;
|
||||||
|
|
||||||
|
const bool write_mentions(const string &filepath, Json::Value &mentions)
|
||||||
|
{
|
||||||
|
const std::regex restrip("<[^>]*>");
|
||||||
|
|
||||||
|
std::ofstream outfile(filepath, std::ios::app);
|
||||||
|
if (outfile.is_open())
|
||||||
|
{
|
||||||
|
cout << filepath << '\n';
|
||||||
|
string output;
|
||||||
|
for (auto &mention : mentions)
|
||||||
|
{
|
||||||
|
output = mention["status"]["account"]["acct"].asString() + ';';
|
||||||
|
output += mention["status"]["created_at"].asString() + ';';
|
||||||
|
output += mention["status"]["content"].asString() + '\n';
|
||||||
|
output = std::regex_replace(output, restrip, "");
|
||||||
|
outfile.write(output.c_str(), output.length());
|
||||||
|
}
|
||||||
|
outfile.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cout << "NOT OPEN" << '\n';
|
||||||
|
cout << filepath << '\n';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Json::Value document;
|
Json::Value document;
|
||||||
|
uint16_t mainret = 0;
|
||||||
if (!read_config(document))
|
if (!read_config(document))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -60,6 +90,10 @@ int main(int argc, char *argv[])
|
||||||
Account *acc = new Account(instance, (*it)["access_token"].asString());
|
Account *acc = new Account(instance, (*it)["access_token"].asString());
|
||||||
acc->set_useragent("mastobotmon/" + string(global::version));
|
acc->set_useragent("mastobotmon/" + string(global::version));
|
||||||
acc->set_minutes((*it)["minutes"].asUInt());
|
acc->set_minutes((*it)["minutes"].asUInt());
|
||||||
|
if (!(*it)["last_mention"].empty())
|
||||||
|
{
|
||||||
|
acc->set_last_mention_id((*it)["last_mention"].asUInt64());
|
||||||
|
}
|
||||||
accounts.push_back(*acc);
|
accounts.push_back(*acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,15 +155,34 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
cout << std::to_string(minutes) << " minutes.\n";
|
cout << std::to_string(minutes) << " minutes.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = acc.get_mentions(answer);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
reader.parse(answer, json);
|
||||||
|
if (!json.empty())
|
||||||
|
{
|
||||||
|
const std::uint64_t lastid = std::stoull(json[0]["id"].asString());
|
||||||
|
const string straccount = acct + "@" + acc.get_instance();
|
||||||
|
acc.set_last_mention_id(lastid);
|
||||||
|
document["accounts"][straccount]["last_mention"] = lastid;
|
||||||
|
write_mentions(document["data_dir"].asString() + "/mentions_" + straccount + ".csv", json);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
cerr << "Error: " << ret << '\n';
|
cerr << "Error: " << ret << '\n';
|
||||||
|
mainret = ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (!write_config(document))
|
||||||
|
{
|
||||||
|
cerr << "Couldn't write config file\n";
|
||||||
|
}
|
||||||
|
return mainret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,25 @@
|
||||||
using std::uint16_t;
|
using std::uint16_t;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
const bool read_config(Json::Value &document);
|
|
||||||
const string get_access_token(const string &account);
|
|
||||||
const bool add_account(Json::Value &document);
|
|
||||||
const bool write_config(Json::Value &document);
|
|
||||||
|
|
||||||
class Account : public Mastodon::API
|
class Account : public Mastodon::API
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Account(const string &instance, const string &access_token);
|
explicit Account(const string &instance, const string &access_token);
|
||||||
const void set_minutes(uint16_t minutes);
|
const void set_minutes(uint16_t minutes);
|
||||||
const uint16_t get_minutes() const;
|
const uint16_t get_minutes() const;
|
||||||
|
const uint16_t get_mentions(string &answer);
|
||||||
|
const void set_last_mention_id(const std::uint64_t &id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t _minutes;
|
uint16_t _minutes;
|
||||||
|
std::uint64_t _last_mention_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bool read_config(Json::Value &document);
|
||||||
|
const string get_access_token(const string &account);
|
||||||
|
const bool add_account(Json::Value &document);
|
||||||
|
const bool write_config(Json::Value &document);
|
||||||
|
|
||||||
|
const bool write_mentions(const string &filepath, Json::Value &mentions);
|
||||||
|
|
||||||
#endif // mastobotmon_HPP
|
#endif // mastobotmon_HPP
|
||||||
|
|
|
@ -30,6 +30,7 @@ using std::uint16_t;
|
||||||
Account::Account(const string &instance, const string &access_token)
|
Account::Account(const string &instance, const string &access_token)
|
||||||
: API(instance, access_token)
|
: API(instance, access_token)
|
||||||
, _minutes(0)
|
, _minutes(0)
|
||||||
|
, _last_mention_id(0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
@ -43,3 +44,18 @@ const uint16_t Account::get_minutes() const
|
||||||
{
|
{
|
||||||
return _minutes;
|
return _minutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint16_t Account::get_mentions(string &answer)
|
||||||
|
{
|
||||||
|
parametermap parameters =
|
||||||
|
{
|
||||||
|
{ "since_id", { std::to_string(_last_mention_id) } },
|
||||||
|
{ "exclude_types", { "follow", "favourite", "reblog" } }
|
||||||
|
};
|
||||||
|
return get(v1::notifications, parameters, answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void Account::set_last_mention_id(const std::uint64_t &id)
|
||||||
|
{
|
||||||
|
_last_mention_id = id;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue