2018-08-30 14:03:25 +02:00
|
|
|
// CC-0, tastytea
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <experimental/filesystem>
|
|
|
|
#include <basedir.h>
|
|
|
|
#include <sqlite/connection.hpp>
|
|
|
|
#include <sqlite/execute.hpp>
|
|
|
|
#include <sqlite/query.hpp>
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include <version.hpp>
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
using std::cout;
|
|
|
|
using std::cerr;
|
|
|
|
using std::cin;
|
|
|
|
namespace fs = std::experimental::filesystem;
|
|
|
|
|
|
|
|
string get_filepath()
|
|
|
|
{
|
|
|
|
string filepath;
|
|
|
|
xdgHandle xdg;
|
|
|
|
xdgInitHandle(&xdg);
|
|
|
|
filepath = xdgDataHome(&xdg);
|
|
|
|
xdgWipeHandle(&xdg);
|
|
|
|
|
2018-08-30 16:54:34 +02:00
|
|
|
filepath += "/whyblocked";
|
2018-08-30 14:03:25 +02:00
|
|
|
if (!fs::exists(filepath))
|
|
|
|
{
|
|
|
|
fs::create_directory(filepath);
|
|
|
|
}
|
|
|
|
filepath += "/database.sqlite";
|
|
|
|
if (!fs::exists(filepath))
|
|
|
|
{
|
|
|
|
sqlite::connection con(filepath);
|
2018-08-30 16:54:34 +02:00
|
|
|
sqlite::execute(con, "CREATE TABLE blocks(user TEXT PRIMARY KEY, "
|
|
|
|
"blocked INTEGER, reason TEXT);", true);
|
2018-08-30 14:03:25 +02:00
|
|
|
sqlite::execute(con, "CREATE TABLE urls(user TEXT, url TEXT);", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return filepath;
|
|
|
|
}
|
|
|
|
|
2018-08-30 16:54:34 +02:00
|
|
|
const void print_help()
|
|
|
|
{
|
|
|
|
cout << "Type add, remove, view or details. Or just the first letter.\n";
|
|
|
|
cout << "Type help or h to show this help. Type quit or q to quit the program.\n";
|
|
|
|
}
|
|
|
|
|
2018-08-30 14:03:25 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
sqlite::connection con(get_filepath());
|
2018-08-30 14:30:44 +02:00
|
|
|
bool keeprunning = true;
|
2018-08-30 14:03:25 +02:00
|
|
|
|
2018-08-30 16:42:28 +02:00
|
|
|
cout << "This is whyblocked " << global::version << ".\n";
|
2018-08-30 16:54:34 +02:00
|
|
|
print_help();
|
2018-08-30 14:30:44 +02:00
|
|
|
while (keeprunning)
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 16:04:11 +02:00
|
|
|
string answer = "";
|
2018-08-30 14:30:44 +02:00
|
|
|
cout << ": ";
|
|
|
|
cin >> answer;
|
|
|
|
switch (answer[0])
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 14:30:44 +02:00
|
|
|
case 'a':
|
|
|
|
case 'A':
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 16:04:11 +02:00
|
|
|
string user, reason;
|
|
|
|
int blocked = -1;
|
2018-08-30 16:40:06 +02:00
|
|
|
cout << "User or instance: ";
|
2018-08-30 16:04:11 +02:00
|
|
|
cin >> user;
|
|
|
|
while (blocked == -1)
|
|
|
|
{
|
|
|
|
cout << "Blocked(b) or silenced(s): ";
|
|
|
|
cin >> answer;
|
|
|
|
if (answer[0] == 'b' || answer[0] == 'B')
|
|
|
|
{
|
|
|
|
blocked = 1;
|
|
|
|
}
|
|
|
|
else if (answer[0] == 's' || answer[0] == 'S')
|
|
|
|
{
|
|
|
|
blocked = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cout << "Reason: ";
|
|
|
|
cin.ignore();
|
|
|
|
std::getline(cin, reason, '\n');
|
|
|
|
|
|
|
|
sqlite::execute ins(con, "INSERT INTO blocks VALUES(?, ?, ?);");
|
|
|
|
ins % user % blocked % reason;
|
|
|
|
ins();
|
2018-08-30 16:54:34 +02:00
|
|
|
cout << user << " added.\n";
|
2018-08-30 16:04:11 +02:00
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
cout << "Add receipt? [y/n] ";
|
|
|
|
cin >> answer;
|
|
|
|
if (answer[0] == 'y' || answer[0] == 'Y')
|
|
|
|
{
|
|
|
|
string url;
|
|
|
|
cout << "URL: ";
|
|
|
|
cin >> url;
|
|
|
|
|
|
|
|
sqlite::execute ins(con, "INSERT INTO urls VALUES(?, ?);");
|
|
|
|
ins % user % url;
|
|
|
|
ins();
|
2018-08-30 16:54:34 +02:00
|
|
|
cout << "Receipt added.\n";
|
2018-08-30 16:04:11 +02:00
|
|
|
}
|
|
|
|
else if (answer[0] == 'n' || answer[0] == 'N')
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
break;
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
case 'r':
|
|
|
|
case 'R':
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 16:40:06 +02:00
|
|
|
string user;
|
|
|
|
cout << "User or instance: ";
|
|
|
|
cin >> user;
|
|
|
|
|
|
|
|
sqlite::execute rm_blocks(con, "DELETE FROM blocks WHERE user = ?;");
|
|
|
|
sqlite::execute rm_urls(con, "DELETE FROM urls WHERE user = ?;");
|
|
|
|
rm_blocks % user;
|
|
|
|
rm_urls % user;
|
|
|
|
rm_blocks();
|
|
|
|
rm_urls();
|
2018-08-30 16:54:34 +02:00
|
|
|
cout << user << " removed.\n";
|
2018-08-30 14:30:44 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'v':
|
|
|
|
case 'V':
|
|
|
|
{
|
|
|
|
sqlite::query q(con, "SELECT * FROM blocks;");
|
2018-08-30 14:03:25 +02:00
|
|
|
boost::shared_ptr<sqlite::result> result = q.get_result();
|
2018-08-30 14:30:44 +02:00
|
|
|
while(result->next_row())
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 14:30:44 +02:00
|
|
|
if (result->get_int(1) == 1)
|
|
|
|
{
|
|
|
|
cout << " Blocked: ";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cout << "Silenced: ";
|
|
|
|
}
|
|
|
|
cout << result->get_string(0) << " because: ";
|
|
|
|
cout << result->get_string(2) << '\n';
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
break;
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
case 'd':
|
|
|
|
case 'D':
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 16:40:06 +02:00
|
|
|
cout << "User or instance: ";
|
2018-08-30 14:30:44 +02:00
|
|
|
cin >> answer;
|
|
|
|
{
|
2018-08-30 16:54:34 +02:00
|
|
|
sqlite::query q(con, "SELECT * FROM blocks WHERE "
|
|
|
|
"user = \'" + answer + "\';");
|
2018-08-30 14:30:44 +02:00
|
|
|
boost::shared_ptr<sqlite::result> result = q.get_result();
|
|
|
|
cout << answer << " is ";
|
|
|
|
if (!result->next_row())
|
|
|
|
{
|
|
|
|
cout << "not in the database.\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (result->get_int(1) == 1)
|
|
|
|
{
|
|
|
|
cout << "blocked, because: ";
|
|
|
|
}
|
|
|
|
else if (result->get_int(1) == 0)
|
|
|
|
{
|
|
|
|
cout << "silenced, because: ";
|
|
|
|
}
|
|
|
|
cout << result->get_string(2) << '\n';
|
|
|
|
}
|
2018-08-30 14:03:25 +02:00
|
|
|
{
|
2018-08-30 14:30:44 +02:00
|
|
|
cout << "Receipts:\n";
|
|
|
|
sqlite::query q(con, "SELECT * FROM urls WHERE user = \'" + answer + "\';");
|
|
|
|
boost::shared_ptr<sqlite::result> result = q.get_result();
|
|
|
|
while(result->next_row())
|
|
|
|
{
|
|
|
|
cout << " " << result->get_string(1) << '\n';
|
|
|
|
}
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
break;
|
2018-08-30 16:54:34 +02:00
|
|
|
case 'h':
|
|
|
|
case 'H':
|
|
|
|
print_help();
|
|
|
|
break;
|
2018-08-30 14:30:44 +02:00
|
|
|
case 'q':
|
|
|
|
case 'Q':
|
|
|
|
keeprunning = false;
|
|
|
|
break;
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
2018-08-30 14:30:44 +02:00
|
|
|
default:
|
|
|
|
cout << "Response not understood.\n";
|
2018-08-30 14:03:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(const std::exception &e)
|
|
|
|
{
|
|
|
|
cerr << "An error occurred: " << e.what() << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|