#include
#include
#include
#include "common.h"
#include "clients/remote_client.h"
#include "clients/rclone.h"
#include "lang.h"
#include "util.h"
#include "system.h"
#include "windows.h"
#include "dbglogger.h"
using httplib::Client;
using httplib::Headers;
using httplib::Result;
std::vector RCloneClient::ListDir(const std::string &path)
{
std::vector out;
DirEntry entry;
Util::SetupPreviousFolder(path, &entry);
out.push_back(entry);
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path)+"/");
if (auto res = client->Get(encoded_path))
{
lxb_status_t status;
lxb_dom_attr_t *attr;
lxb_dom_element_t *tbody_element, *tr_element, *td_element;
lxb_html_document_t *document;
lxb_dom_collection_t *tbody_collection;
lxb_dom_collection_t *tr_collection;
lxb_dom_collection_t *td_collection;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
{
lxb_html_document_destroy(document);
goto finish;
}
tbody_collection = lxb_dom_collection_make(&document->dom_document, 1);
if (tbody_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
tr_collection = lxb_dom_collection_make(&document->dom_document, 128);
if (tbody_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
tbody_collection, (const lxb_char_t *)"tbody", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
if (lxb_dom_collection_length(tbody_collection) < 1)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// Get the first tbody which should only be 1
tbody_element = lxb_dom_collection_element(tbody_collection, 0);
status = lxb_dom_elements_by_tag_name(tbody_element,
tr_collection, (const lxb_char_t *)"tr", 2);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// skip row 0 , since it has the previous folder header
for (size_t i = 1; i < lxb_dom_collection_length(tr_collection); i++)
{
DirEntry entry;
std::string title, aclass;
memset(&entry.modified, 0, sizeof(DateTime));
const lxb_char_t *value;
size_t value_len;
std::string tmp_string;
tr_element = lxb_dom_collection_element(tr_collection, i);
td_collection = lxb_dom_collection_make(&document->dom_document, 5);
status = lxb_dom_elements_by_tag_name(tr_element,
td_collection, (const lxb_char_t *)"td", 2);
if (status != LXB_STATUS_OK || lxb_dom_collection_length(td_collection) < 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// td 0 is empty, td 1 is file or folder
td_element = lxb_dom_collection_element(td_collection, 1);
lxb_dom_node_t *use_node = NextChildElement(lxb_dom_interface_element(NextChildElement(td_element)));
value = lxb_dom_element_local_name(lxb_dom_interface_element(use_node), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("use") != 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(use_node), (const lxb_char_t *)"xlink:href", 10, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("#folder") == 0)
{
entry.isDir = true;
entry.selectable = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]);
}
else
{
entry.isDir = false;
entry.selectable = true;
}
// element contains the file/folder name
lxb_dom_node_t *a_node = NextChildElement(lxb_dom_interface_element(NextElement(NextChildElement(td_element))));
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string[tmp_string.length()-1] == '/')
tmp_string = tmp_string.substr(0, tmp_string.length()-1);
tmp_string = BaseClient::DecodeUrl(tmp_string);
sprintf(entry.name, "%s", tmp_string.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
}
// td 3 - filesize
if (!entry.isDir)
{
td_element = lxb_dom_collection_element(td_collection, 2);
lxb_dom_node_t *size_node = NextChildElement(td_element);
value = lxb_dom_node_text_content(size_node->first_child, &value_len);
tmp_string = std::string((const char *)value, value_len);
entry.file_size = atol(tmp_string.c_str());
DirEntry::SetDisplaySize(&entry);
}
// td 4 - datetime
td_element = lxb_dom_collection_element(td_collection, 3);
lxb_dom_node_t *date_node = NextChildElement(td_element);
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(date_node), (const lxb_char_t *)"datetime", 8, &value_len);
tmp_string = std::string((const char *)value, value_len);
std::vector date_time = Util::Split(tmp_string, " ");
OrbisDateTime gmt;
OrbisDateTime lt;
if (date_time.size() > 1)
{
std::vector adate = Util::Split(date_time[0], "-");
if (adate.size() == 3)
{
gmt.year = atoi(adate[0].c_str());
gmt.month = atoi(adate[1].c_str());
gmt.day = atoi(adate[2].c_str());
}
std::vector atime = Util::Split(date_time[1], ":");
if (atime.size() == 3)
{
gmt.hour = atoi(atime[0].c_str());
gmt.minute = atoi(atime[1].c_str());
std::vector sec_msec = Util::Split(atime[2], ".");
if (sec_msec.size() > 0)
{
gmt.second = atoi(sec_msec[0].c_str());
}
}
}
convertUtcToLocalTime(&gmt, <);
entry.modified.day = lt.day;
entry.modified.month = lt.month;
entry.modified.year = lt.year;
entry.modified.hours = lt.hour;
entry.modified.minutes = lt.minute;
entry.modified.seconds = lt.second;
lxb_dom_collection_destroy(td_collection, true);
out.push_back(entry);
}
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
return out;
}
finish:
return out;
}