Implement IPFS network stats popover

master
Melroy van den Berg 2021-03-28 00:50:04 +01:00
parent 1683df3af7
commit bf294d4617
5 changed files with 71 additions and 15 deletions

@ -1 +1 @@
Subproject commit aa0d1a4e9e64a258583f41b5a09e03d0cf5fac07
Subproject commit c6af4bfbf02729b80ccb2ccc378361b6139bd402

View File

@ -23,7 +23,11 @@ namespace n_fs = ::std::filesystem;
*/
IPFS::IPFS(const std::string &host, int port) : client(host, port, "6s") {}
std::size_t IPFS::getPeers()
/**
* \brief Get the number of IPFS peers
* \return number of peers
*/
std::size_t IPFS::getNrPeers()
{
try
{
@ -38,6 +42,29 @@ std::size_t IPFS::getPeers()
return 0;
}
/**
* \brief Get the number of IPFS peers
* \return Map with bandwidth information (with keys: 'in' and 'out')
*/
std::map<std::string, float> IPFS::getBandwidthRates()
{
std::map<std::string, float> bandwidthRates;
try
{
ipfs::Json bandwidth_info;
client.StatsBw(&bandwidth_info);
float in = bandwidth_info["RateIn"];
float out = bandwidth_info["RateOut"];
bandwidthRates.insert(std::pair<std::string, float>("in", in));
bandwidthRates.insert(std::pair<std::string, float>("out", out));
}
catch (const std::runtime_error &error)
{
// ignore connection issues
}
return bandwidthRates;
}
/**
* \brief Start IPFS Daemon
* \return exit code

View File

@ -14,7 +14,8 @@ public:
explicit IPFS(const std::string &host, int port);
static int startIPFSDaemon();
std::size_t getPeers();
std::size_t getNrPeers();
std::map<std::string, float> getBandwidthRates();
private:
ipfs::Client client;

View File

@ -26,6 +26,7 @@ MainWindow::MainWindow()
m_hboxFormattingEditorToolbar(Gtk::ORIENTATION_HORIZONTAL, 0),
m_hboxBottom(Gtk::ORIENTATION_HORIZONTAL, 0),
m_searchMatchCase("Match _Case", true),
m_statusPopover(m_statusButton),
m_appName("LibreWeb Browser"),
m_iconTheme("flat"), // filled or flat
m_useCurrentGTKIconTheme(false), // Use our built-in icon theme or the GTK icons
@ -42,8 +43,15 @@ MainWindow::MainWindow()
set_position(Gtk::WIN_POS_CENTER);
add_accel_group(accelGroup);
m_statusPopover.set_position(Gtk::POS_BOTTOM);
m_statusPopover.set_size_request(200, 80);
m_statusPopover.add(m_statusLabel);
m_statusLabel.set_text("Network is still starting..."); // fallback text
m_statusPopover.show_all_children();
// Timeouts
this->statusTimerHandler = Glib::signal_timeout().connect(sigc::mem_fun(this, &MainWindow::update_connect_status), 3000);
this->statusTimerHandler = Glib::signal_timeout().connect(sigc::mem_fun(this, &MainWindow::update_connection_status), 3000);
// Connect signals
m_menu.new_doc.connect(sigc::mem_fun(this, &MainWindow::new_doc)); /*!< Menu item for new document */
@ -75,6 +83,7 @@ MainWindow::MainWindow()
m_forwardButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::forward)); /*!< Button for next page */
m_refreshButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::refresh)); /*!< Button for reloading the page */
m_homeButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::go_home)); /*!< Button for home page */
m_statusButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::show_status)); /*!< Button for IPFS status */
m_searchEntry.signal_activate().connect(sigc::mem_fun(this, &MainWindow::on_search)); /*!< Execute the text search */
m_searchReplaceEntry.signal_activate().connect(sigc::mem_fun(this, &MainWindow::on_replace)); /*!< Execute the text replace */
@ -361,7 +370,7 @@ MainWindow::MainWindow()
// First time manually trigger the status update once,
// timer will do the updates later
this->update_connect_status();
this->update_connection_status();
#ifdef NDEBUG
// Show start page by default
@ -398,11 +407,10 @@ void MainWindow::doRequest(const std::string &path, bool setAddressBar, bool isH
/**
* \brief Timeout slot: Update the IPFS connection status every x seconds
*/
bool MainWindow::update_connect_status()
bool MainWindow::update_connection_status()
{
std::size_t peers = ipfs.getPeers();
// TODO: Catch the pixbuf images, instead of reading from disk every time
if (peers > 0)
std::size_t nrPeers = ipfs.getNrPeers();
if (nrPeers > 0)
{
if (m_useCurrentGTKIconTheme)
{
@ -412,6 +420,15 @@ bool MainWindow::update_connect_status()
{
m_statusIcon.set(m_statusOnlineIcon);
}
std::map<std::string, float> rates = ipfs.getBandwidthRates();
char buf[32];
std::string in = std::string(buf, std::snprintf(buf, sizeof buf, "%.1f", rates.at("in") / 1000.0));
std::string out = std::string(buf, std::snprintf(buf, sizeof buf, "%.1f", rates.at("out") / 1000.0));
// And also update text
m_statusLabel.set_text("IPFS Network Stats:\n\nConnected peers: " + std::to_string(nrPeers) +
"\nRate in: " + in + " kB/s" +
"\nRate out: " + out + " kB/s");
}
else
{
@ -423,6 +440,7 @@ bool MainWindow::update_connect_status()
{
m_statusIcon.set(m_statusOfflineIcon);
}
m_statusLabel.set_text("Disconnected!");
}
// Keep going (do not disconnect yet)
@ -650,6 +668,11 @@ void MainWindow::go_home()
m_draw_main.showStartPage();
}
void MainWindow::show_status()
{
this->m_statusPopover.popup();
}
/**
* Trigger when pressed enter in the search entry
*/

View File

@ -1,6 +1,12 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "menu.h"
#include "about.h"
#include "source-code-dialog.h"
#include "draw.h"
#include "ipfs.h"
#include <gtkmm/window.h>
#include <gtkmm/box.h>
#include <gtkmm/menubar.h>
@ -8,16 +14,12 @@
#include <gtkmm/button.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/popover.h>
#include <gtkmm/entry.h>
#include <gtkmm/searchbar.h>
#include <gtkmm/searchentry.h>
#include <gtkmm/paned.h>
#include <thread>
#include "menu.h"
#include "about.h"
#include "source-code-dialog.h"
#include "draw.h"
#include "ipfs.h"
/**
* \class MainWindow
@ -31,7 +33,7 @@ public:
protected:
// Signal handlers
bool update_connect_status();
bool update_connection_status();
void cut();
void copy();
void paste();
@ -43,6 +45,7 @@ protected:
void save_as();
void publish();
void go_home();
void show_status();
void address_bar_activate();
void on_search();
void on_replace();
@ -130,6 +133,8 @@ protected:
Gtk::Image m_bulletListIcon;
Gtk::Image m_numberedListIcon;
Gtk::Image m_hightlightIcon;
Gtk::Popover m_statusPopover;
Gtk::Label m_statusLabel;
Gtk::ScrolledWindow m_scrolledWindowMain;
Gtk::ScrolledWindow m_scrolledWindowSecondary;
Gtk::Button m_exitBottomButton;