Refactored, made it easier to add more interfaces
parent
133f7f9c2a
commit
1b8be98493
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required (VERSION 3.7)
|
||||
project (whyblocked
|
||||
VERSION 0.5.0
|
||||
VERSION 0.6.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/* This file is part of whyblocked.
|
||||
* Copyright © 2018 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "version.hpp"
|
||||
#include "whyblocked.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::cin;
|
||||
|
||||
const void whyblocked_text::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";
|
||||
}
|
||||
|
||||
const bool whyblocked_text::start()
|
||||
{
|
||||
bool keeprunning = true;
|
||||
|
||||
cout << "This is whyblocked " << global::version << ".\n";
|
||||
print_help();
|
||||
while (keeprunning)
|
||||
{
|
||||
string answer = "";
|
||||
cout << ": ";
|
||||
cin >> answer;
|
||||
switch (answer[0])
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
{
|
||||
string user, reason;
|
||||
int blocked = -1;
|
||||
cout << "User or instance: ";
|
||||
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');
|
||||
|
||||
if (add_block(user, blocked, reason))
|
||||
{
|
||||
cout << user << " added.\n";
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
cout << "Add receipt? [y/n] ";
|
||||
cin >> answer;
|
||||
if (answer[0] == 'y' || answer[0] == 'Y')
|
||||
{
|
||||
string url;
|
||||
cout << "URL: ";
|
||||
cin >> url;
|
||||
|
||||
if (add_url(user, url))
|
||||
{
|
||||
cout << "Receipt added.\n";
|
||||
}
|
||||
}
|
||||
else if (answer[0] == 'n' || answer[0] == 'N')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
case 'R':
|
||||
{
|
||||
string user;
|
||||
cout << "User or instance: ";
|
||||
cin >> user;
|
||||
|
||||
if (remove(user))
|
||||
{
|
||||
cout << user << " removed.\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
case 'V':
|
||||
{
|
||||
result_view result;
|
||||
if (view(result))
|
||||
{
|
||||
for (const std::tuple<string, int, string> &line : result)
|
||||
{
|
||||
if (std::get<1>(line) == 1)
|
||||
{
|
||||
cout << " Blocked: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Silenced: ";
|
||||
}
|
||||
cout << std::get<0>(line) << " because: ";
|
||||
cout << std::get<2>(line) << '\n';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'D':
|
||||
{
|
||||
cout << "User or instance: ";
|
||||
cin >> answer;
|
||||
{
|
||||
result_details result;
|
||||
if (details(answer, result))
|
||||
{
|
||||
cout << answer << " is ";
|
||||
if (std::get<0>(result) == 1)
|
||||
{
|
||||
cout << "blocked, because: ";
|
||||
}
|
||||
else if (std::get<0>(result) == 0)
|
||||
{
|
||||
cout << "silenced, because: ";
|
||||
}
|
||||
cout << std::get<1>(result) << '\n';
|
||||
|
||||
cout << "Receipts:\n";
|
||||
for (const string &url : std::get<2>(result))
|
||||
{
|
||||
cout << " " << url << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
case 'H':
|
||||
{
|
||||
print_help();
|
||||
break;
|
||||
}
|
||||
case 'q':
|
||||
case 'Q':
|
||||
{
|
||||
keeprunning = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cout << "Response not understood.\n";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
213
src/whyblock.cpp
213
src/whyblock.cpp
|
@ -1,213 +0,0 @@
|
|||
// 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);
|
||||
|
||||
filepath += "/whyblocked";
|
||||
if (!fs::exists(filepath))
|
||||
{
|
||||
fs::create_directory(filepath);
|
||||
}
|
||||
filepath += "/database.sqlite";
|
||||
if (!fs::exists(filepath))
|
||||
{
|
||||
sqlite::connection con(filepath);
|
||||
sqlite::execute(con, "CREATE TABLE blocks(user TEXT PRIMARY KEY, "
|
||||
"blocked INTEGER, reason TEXT);", true);
|
||||
sqlite::execute(con, "CREATE TABLE urls(user TEXT, url TEXT);", true);
|
||||
}
|
||||
|
||||
return filepath;
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
bool keeprunning = true;
|
||||
|
||||
cout << "This is whyblocked " << global::version << ".\n";
|
||||
print_help();
|
||||
while (keeprunning)
|
||||
{
|
||||
string answer = "";
|
||||
cout << ": ";
|
||||
cin >> answer;
|
||||
switch (answer[0])
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
{
|
||||
string user, reason;
|
||||
int blocked = -1;
|
||||
cout << "User or instance: ";
|
||||
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();
|
||||
cout << user << " added.\n";
|
||||
|
||||
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();
|
||||
cout << "Receipt added.\n";
|
||||
}
|
||||
else if (answer[0] == 'n' || answer[0] == 'N')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
case 'R':
|
||||
{
|
||||
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();
|
||||
cout << user << " removed.\n";
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
case 'V':
|
||||
{
|
||||
sqlite::query q(con, "SELECT * FROM blocks;");
|
||||
boost::shared_ptr<sqlite::result> result = q.get_result();
|
||||
while(result->next_row())
|
||||
{
|
||||
if (result->get_int(1) == 1)
|
||||
{
|
||||
cout << " Blocked: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Silenced: ";
|
||||
}
|
||||
cout << result->get_string(0) << " because: ";
|
||||
cout << result->get_string(2) << '\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'D':
|
||||
{
|
||||
cout << "User or instance: ";
|
||||
cin >> answer;
|
||||
{
|
||||
sqlite::query q(con, "SELECT * FROM blocks WHERE "
|
||||
"user = \'" + answer + "\';");
|
||||
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';
|
||||
}
|
||||
{
|
||||
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';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
print_help();
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
keeprunning = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cout << "Response not understood.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/* This file is part of whyblocked.
|
||||
* Copyright © 2018 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <experimental/filesystem>
|
||||
#include <basedir.h>
|
||||
#include <sqlite/connection.hpp>
|
||||
#include <sqlite/execute.hpp>
|
||||
#include <sqlite/query.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "whyblocked.hpp"
|
||||
|
||||
using std::cerr;
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const string get_filepath()
|
||||
{
|
||||
string filepath;
|
||||
xdgHandle xdg;
|
||||
xdgInitHandle(&xdg);
|
||||
filepath = xdgDataHome(&xdg);
|
||||
xdgWipeHandle(&xdg);
|
||||
|
||||
filepath += "/whyblocked";
|
||||
if (!fs::exists(filepath))
|
||||
{
|
||||
fs::create_directory(filepath);
|
||||
}
|
||||
filepath += "/database.sqlite";
|
||||
if (!fs::exists(filepath))
|
||||
{
|
||||
sqlite::connection con(filepath);
|
||||
sqlite::execute(con, "CREATE TABLE blocks(user TEXT PRIMARY KEY, "
|
||||
"blocked INTEGER, reason TEXT);", true);
|
||||
sqlite::execute(con, "CREATE TABLE urls(user TEXT, url TEXT);", true);
|
||||
}
|
||||
|
||||
return filepath;
|
||||
}
|
||||
|
||||
const bool add_block(const string &user, const int blocked, const string &reason)
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
sqlite::execute ins(con, "INSERT INTO blocks VALUES(?, ?, ?);");
|
||||
ins % user % blocked % reason;
|
||||
ins();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool add_url(const string &user, const string &url)
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
sqlite::execute ins(con, "INSERT INTO urls VALUES(?, ?);");
|
||||
ins % user % url;
|
||||
ins();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool remove(const string &user)
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
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();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool view(result_view &result)
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
sqlite::query q(con, "SELECT * FROM blocks;");
|
||||
boost::shared_ptr<sqlite::result> res = q.get_result();
|
||||
while(res->next_row())
|
||||
{
|
||||
result.push_back(
|
||||
{
|
||||
res->get_string(0),
|
||||
res->get_int(1),
|
||||
res->get_string(2)
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool details(const string &user, result_details &result)
|
||||
{
|
||||
try
|
||||
{
|
||||
sqlite::connection con(get_filepath());
|
||||
sqlite::query q_blocks(con, "SELECT * FROM blocks WHERE user = \'" + user + "\';");
|
||||
boost::shared_ptr<sqlite::result> res_blocks = q_blocks.get_result();
|
||||
|
||||
sqlite::query q_urls(con, "SELECT * FROM urls WHERE user = \'" + user + "\';");
|
||||
boost::shared_ptr<sqlite::result> res_urls = q_urls.get_result();
|
||||
|
||||
if (!res_blocks->next_row())
|
||||
{
|
||||
cerr << user << " is not in the database.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<string> urls;
|
||||
while (res_urls->next_row())
|
||||
{
|
||||
urls.push_back(res_urls->get_string(1));
|
||||
}
|
||||
|
||||
result =
|
||||
{
|
||||
res_blocks->get_int(1),
|
||||
res_blocks->get_string(2),
|
||||
urls
|
||||
};
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
whyblocked_text::start();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* This file is part of whyblocked.
|
||||
* Copyright © 2018 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WHYBLOCKED_HPP
|
||||
#define WHYBLOCKED_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using result_view = std::vector<std::tuple<string, int, string>>;
|
||||
using result_details = std::tuple<int, string, std::vector<string>>;
|
||||
|
||||
const string get_filepath();
|
||||
const bool add_block(const string &user, const int blocked, const string &reason);
|
||||
const bool add_url(const string &user, const string &url);
|
||||
const bool remove(const string &user);
|
||||
const bool view(result_view &result);
|
||||
const bool details(const string &user, result_details &result);
|
||||
|
||||
namespace whyblocked_text
|
||||
{
|
||||
const void print_help();
|
||||
const bool start();
|
||||
}
|
||||
|
||||
#endif // WHYBLOCKED_HPP
|
Loading…
Reference in New Issue