345 lines
8.6 KiB
C++
345 lines
8.6 KiB
C++
|
#include "mainwindow.h"
|
||
|
#include "ui_mainwindow.h"
|
||
|
#include "downloadfile.h"
|
||
|
#include "tools.h"
|
||
|
#include <iostream>
|
||
|
#include <KTreeWidgetSearchLineWidget>
|
||
|
#include <pstreams/pstream.h>
|
||
|
#include <sstream>
|
||
|
#include <string>
|
||
|
#include <cstring>
|
||
|
#include <iostream>
|
||
|
#include <stdio.h>
|
||
|
#include <QMessageBox>
|
||
|
#include <vector>
|
||
|
#include <boost/algorithm/string/replace.hpp>
|
||
|
#include <QFuture>
|
||
|
#include <QtConcurrent>
|
||
|
#include <qtconcurrentrun.h>
|
||
|
#include <QFileDialog>
|
||
|
#include <QThread>
|
||
|
#include <QProgressDialog>
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
bool display = false;
|
||
|
|
||
|
MainWindow::MainWindow(QWidget *parent)
|
||
|
: QMainWindow(parent)
|
||
|
, ui(new Ui::MainWindow)
|
||
|
{
|
||
|
ui->setupUi(this);
|
||
|
ui->ktreewidgetsearchline->setTreeWidget(ui->treeWidget);
|
||
|
ui->ktreewidgetsearchline->setCaseSensitivity(Qt::CaseInsensitive);
|
||
|
ui->treeWidget->setHeaderLabels({tr("Path"), tr("Size")} );
|
||
|
ui->progressBar->hide();
|
||
|
populateList();
|
||
|
}
|
||
|
|
||
|
MainWindow::~MainWindow()
|
||
|
{
|
||
|
delete ui;
|
||
|
}
|
||
|
|
||
|
void MainWindow::populateTree()
|
||
|
{
|
||
|
string server;
|
||
|
string port;
|
||
|
int portN;
|
||
|
stringstream ss;
|
||
|
vector<string> path;
|
||
|
|
||
|
server.assign(ui->khistorycombobox->currentText().toStdString());
|
||
|
port.assign(ui->portEdit->text().toStdString());
|
||
|
ss << port;
|
||
|
ss >> portN;
|
||
|
if (!server.empty() and !port.empty() and portN < 65536)
|
||
|
{
|
||
|
if (validateServer(server))
|
||
|
{
|
||
|
ui->treeWidget->cursor().setShape(Qt::WaitCursor);
|
||
|
path = explode(ui->listWidget->currentItem()->text().toStdString(), '\n', 2);
|
||
|
scanDir(server, portN, NULL, path[0].append("/") );
|
||
|
ui->treeWidget->cursor().setShape(Qt::ArrowCursor);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainWindow::populateList()
|
||
|
{
|
||
|
string server;
|
||
|
string port;
|
||
|
int portN;
|
||
|
stringstream ss;
|
||
|
|
||
|
server.assign(ui->khistorycombobox->currentText().toStdString());
|
||
|
port.assign(ui->portEdit->text().toStdString());
|
||
|
ss << port;
|
||
|
ss >> portN;
|
||
|
if (!server.empty() and !port.empty() and portN < 65536)
|
||
|
{
|
||
|
if (validateServer(server))
|
||
|
{
|
||
|
ui->centralwidget->cursor().setShape(Qt::WaitCursor);
|
||
|
listServices(server, portN);
|
||
|
ui->centralwidget->cursor().setShape(Qt::ArrowCursor);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainWindow::listServices(string server, int portN)
|
||
|
{
|
||
|
char cmd[4096];
|
||
|
string line;
|
||
|
string errorRsync;
|
||
|
vector<string> v;
|
||
|
char service[4096];
|
||
|
|
||
|
sprintf(cmd, "rsync --contimeout=10 -P \"%s::\" --port %d ", server.c_str(), portN );
|
||
|
redi::ipstream in(cmd, redi::pstreams::pstdout | redi::pstreams::pstderr);
|
||
|
while (getline(in.out(), line))
|
||
|
{
|
||
|
cout << "stdout: " << line << endl;
|
||
|
boost::replace_all(line," ","");
|
||
|
boost::replace_all(line, "\t", " - ");
|
||
|
v = explode(line, ' ', 3 );
|
||
|
sprintf(service, "%s\n\t%s", v[0].c_str(), v[2].c_str());
|
||
|
ui->listWidget->addItem(service);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainWindow::scanDir(string server, int portN, QTreeWidgetItem *parent, string path)
|
||
|
{
|
||
|
char cmd[4096];
|
||
|
string line;
|
||
|
string errorRsync;
|
||
|
vector<string> v;
|
||
|
QTreeWidgetItem * item;
|
||
|
char npath[4096];
|
||
|
|
||
|
sprintf(cmd, "rsync --contimeout=10 -P \"%s::%s\" --port %d ", server.c_str(), path.c_str(), portN );
|
||
|
redi::ipstream in(cmd, redi::pstreams::pstdout | redi::pstreams::pstderr);
|
||
|
|
||
|
while (getline(in.out(), line))
|
||
|
{
|
||
|
|
||
|
v = explode(line, ' ', 5);
|
||
|
if (v.size() == 5)
|
||
|
{
|
||
|
if (v[4].at(0) != '.' and (v[0].at(0) == '-' or v[0].at(0) == 'd'))
|
||
|
{
|
||
|
if (parent != NULL)
|
||
|
{
|
||
|
item = addTreeChild(parent,QString::fromStdString(v[4]), QString::fromStdString(v[1]));
|
||
|
}else
|
||
|
{
|
||
|
item = addTreeRoot(QString::fromStdString(v[4]), QString::fromStdString(v[1]));
|
||
|
}
|
||
|
if (v[0].at(0) == 'd')
|
||
|
{
|
||
|
sprintf(npath, "%s%s/", path.c_str(), v[4].c_str());
|
||
|
scanDir(server, portN, item, npath);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// if reading stdout stopped at EOF then reset the state:
|
||
|
if (in.eof() && in.fail())
|
||
|
in.clear();
|
||
|
// read child's stderr
|
||
|
while (getline(in.err(), line))
|
||
|
{
|
||
|
cout << "stderr: " << line << endl;
|
||
|
errorRsync.append(line);
|
||
|
errorRsync.append("\n");
|
||
|
}
|
||
|
if ( !errorRsync.empty())
|
||
|
{
|
||
|
QMessageBox::warning(
|
||
|
this,
|
||
|
"RsyncUI",
|
||
|
errorRsync.c_str());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
bool MainWindow::isIpAddress(string server)
|
||
|
{
|
||
|
bool returnCode = false;
|
||
|
vector<string> r;
|
||
|
stringstream ss;
|
||
|
int elementN;
|
||
|
|
||
|
r = explode(server, '.');
|
||
|
if (r.size() == 4)
|
||
|
{
|
||
|
for (auto element : r)
|
||
|
{
|
||
|
ss << element;
|
||
|
ss >> elementN;
|
||
|
if (elementN >0 and elementN < 256)
|
||
|
{
|
||
|
returnCode &= true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return returnCode;
|
||
|
}
|
||
|
|
||
|
bool MainWindow::validateServer(string server)
|
||
|
{
|
||
|
char cmd[512];
|
||
|
string line;
|
||
|
string errorDig;
|
||
|
bool flag = false;
|
||
|
|
||
|
sprintf(cmd, "dig %s", server.c_str());
|
||
|
redi::ipstream in(cmd, redi::pstreams::pstdout | redi::pstreams::pstderr);
|
||
|
|
||
|
while (getline(in.out(), line))
|
||
|
{
|
||
|
cout << "stdout: " << line << '\n';
|
||
|
if (line.find(";; ANSWER SECTION:") != string::npos)
|
||
|
{
|
||
|
flag = true;
|
||
|
}
|
||
|
}
|
||
|
// if reading stdout stopped at EOF then reset the state:
|
||
|
if (in.eof() && in.fail())
|
||
|
in.clear();
|
||
|
// read child's stderr
|
||
|
while (std::getline(in.err(), line))
|
||
|
{
|
||
|
cout << "stderr: " << line << '\n';
|
||
|
errorDig.append(line);
|
||
|
errorDig.append("\n");
|
||
|
}
|
||
|
if ( !errorDig.empty())
|
||
|
{
|
||
|
QMessageBox::warning(
|
||
|
this,
|
||
|
"RsyncUI",
|
||
|
errorDig.c_str()
|
||
|
);
|
||
|
}
|
||
|
if ( flag == false)
|
||
|
{
|
||
|
flag = isIpAddress(server);
|
||
|
QMessageBox::warning(
|
||
|
this,
|
||
|
"RsyncUI",
|
||
|
tr("server does not exists" )
|
||
|
);
|
||
|
}
|
||
|
return flag;
|
||
|
}
|
||
|
|
||
|
void MainWindow::displayTree()
|
||
|
{
|
||
|
populateTree();
|
||
|
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_khistorycombobox_returnPressed()
|
||
|
{
|
||
|
populateList();
|
||
|
}
|
||
|
|
||
|
/*void MainWindow::on_portEdit_userTextChanged()
|
||
|
{
|
||
|
populateTree();
|
||
|
}*/
|
||
|
|
||
|
void MainWindow::on_portEdit_returnPressed()
|
||
|
{
|
||
|
populateList();
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_khistorycombobox_textActivated()
|
||
|
{
|
||
|
populateList();
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_treeWidget_customContextMenuRequested()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_actionDownload_triggered()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
QTreeWidgetItem * MainWindow::addTreeRoot(QString name, QString fileSize)
|
||
|
{
|
||
|
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
|
||
|
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui->treeWidget);
|
||
|
|
||
|
// QTreeWidgetItem::setText(int column, const QString & text)
|
||
|
treeItem->setText(0, name);
|
||
|
treeItem->setText(1, fileSize);
|
||
|
return treeItem;
|
||
|
}
|
||
|
|
||
|
QTreeWidgetItem * MainWindow::addTreeChild(QTreeWidgetItem *parent, QString name, QString fileSize)
|
||
|
{
|
||
|
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
|
||
|
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
|
||
|
|
||
|
// QTreeWidgetItem::setText(int column, const QString & text)
|
||
|
treeItem->setText(0, name);
|
||
|
treeItem->setText(1, fileSize);
|
||
|
|
||
|
// QTreeWidgetItem::addChild(QTreeWidgetItem * child)
|
||
|
parent->addChild(treeItem);
|
||
|
return treeItem;
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_listWidget_clicked(const QModelIndex &index)
|
||
|
{
|
||
|
populateTree();
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_listDownload_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
|
||
|
{
|
||
|
cout << current->text().toStdString() << endl;
|
||
|
}
|
||
|
|
||
|
void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
|
||
|
{
|
||
|
string path;
|
||
|
QFuture<void> future;
|
||
|
QFutureWatcher<void> watcher;
|
||
|
QString savePath;
|
||
|
QFileDialog dialog;
|
||
|
QString dirPath;
|
||
|
/*int p[2];
|
||
|
|
||
|
if (pipe(p) < 0)
|
||
|
{
|
||
|
return;
|
||
|
}*/
|
||
|
dirPath = getenv("HOME");
|
||
|
dirPath.append("/Vidéos/");
|
||
|
savePath = dialog.getExistingDirectory(this, tr("Choose directory to save file"), dirPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||
|
downloadFile downloadO;
|
||
|
|
||
|
|
||
|
//QProgressDialog progress("Downloading file ...", "Abort Download", 0, 100, this);
|
||
|
|
||
|
ui->progressBar->setWindowModality(Qt::WindowModal);
|
||
|
ui->progressBar->setValue(0);
|
||
|
ui->progressBar->show();
|
||
|
connect(&watcher, &QFutureWatcherBase::finished, ui->progressBar, &QProgressBar::hide);
|
||
|
connect(&downloadO, &downloadFile::progressSignal, ui->progressBar, &QProgressBar::setValue);
|
||
|
future = QtConcurrent::run(&this->MyObject, &downloadFile::download, savePath, this);
|
||
|
watcher.setFuture(future);
|
||
|
}
|