restructure of class to prepare folder sync

pull/23/head
JuanJakobo 2021-02-12 16:44:22 +01:00
parent 86b1346aa7
commit e86395264e
5 changed files with 153 additions and 78 deletions

View File

@ -142,22 +142,38 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
int itemID = _listView->listClicked(par1, par2); int itemID = _listView->listClicked(par1, par2);
if (itemID != -1) if (itemID != -1)
{ {
if (_nextcloud.getItems()->at(itemID).getType() == Itemtype::IFOLDER) if (_nextcloud.getItems().at(itemID).getType() == Itemtype::IFOLDER)
{ {
//TODO temp solution --> remove solution
//TODO if is the first option, go back and dont ask for sync
int dialogResult = DialogSynchro(ICON_QUESTION, "Action", "What do you want to to do?", "Open folder", "Sync Folder", "Cancel");
switch (dialogResult)
{
case 1:
FillAreaRect(_menu.getContentRect(), WHITE); FillAreaRect(_menu.getContentRect(), WHITE);
_menu.drawLoadingScreen(); _menu.drawLoadingScreen();
_tempPath = _nextcloud.getItems()->at(itemID).getPath(); _tempPath = _nextcloud.getItems().at(itemID).getPath();
if (!_tempPath.empty()) if (!_tempPath.empty())
_nextcloud.getDataStructure(_tempPath); _nextcloud.setItems(_nextcloud.getDataStructure(_tempPath));
_listView.reset(new ListView(_menu.getContentRect(), _nextcloud.getItems())); _listView.reset(new ListView(_menu.getContentRect(), _nextcloud.getItems()));
_listView->drawHeader(_tempPath.substr(NEXTCLOUD_ROOT_PATH.length())); _listView->drawHeader(_tempPath.substr(NEXTCLOUD_ROOT_PATH.length()));
break;
case 2:
//Sync folder
_nextcloud.downloadFolder(_nextcloud.getItems(), itemID);
//update the entry and say --> folder is synced
//entries in visual and in nextlcoud are out of sync
default:
break;
}
} }
else else
{ {
int dialogResult = 0; int dialogResult = 0;
if (_nextcloud.getItems()->at(itemID).getState() != FileState::ICLOUD) if (_nextcloud.getItems().at(itemID).getState() != FileState::ICLOUD)
{ {
dialogResult = DialogSynchro(ICON_QUESTION, "Action", "What do you want to do?", "Open", "Remove", "Cancel"); dialogResult = DialogSynchro(ICON_QUESTION, "Action", "What do you want to do?", "Open", "Remove", "Cancel");
} }
@ -165,10 +181,10 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
switch (dialogResult) switch (dialogResult)
{ {
case 1: case 1:
_nextcloud.getItems()->at(itemID).open(); _nextcloud.getItems().at(itemID).open();
break; break;
case 2: case 2:
if (!_nextcloud.getItems()->at(itemID).removeFile()) if (!_nextcloud.getItems().at(itemID).removeFile())
Message(ICON_WARNING, "Warning", "Could not delete the file, please try again.", 1200); Message(ICON_WARNING, "Warning", "Could not delete the file, please try again.", 1200);
break; break;
case 3: case 3:
@ -199,12 +215,18 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
if (_loginView->logginClicked(par1, par2) == 2) if (_loginView->logginClicked(par1, par2) == 2)
{ {
_menu.drawLoadingScreen(); _menu.drawLoadingScreen();
//TODO use progressbar and log (check what can go wrong?) catch?
if (_nextcloud.login(_loginView->getURL(), _loginView->getUsername(), _loginView->getPassword())) if (_nextcloud.login(_loginView->getURL(), _loginView->getUsername(), _loginView->getPassword()))
{ {
_listView = std::unique_ptr<ListView>(new ListView(_menu.getContentRect(), _nextcloud.getItems())); _listView = std::unique_ptr<ListView>(new ListView(_menu.getContentRect(), _nextcloud.getItems()));
_loginView.reset(); _loginView.reset();
FullUpdate();
} }
else
{
//redraw login screen so that loading disappears
Message(ICON_WARNING, "Warning", "Something went wrong...", 1200);
}
FullUpdate();
return 1; return 1;
} }
} }

View File

@ -19,7 +19,7 @@
using std::string; using std::string;
using std::vector; using std::vector;
ListView::ListView(const irect *contentRect, const std::shared_ptr<vector<Item>> items) : _contentRect(contentRect), _items(items) ListView::ListView(const irect *contentRect, const vector<Item> items) : _contentRect(contentRect), _items(items)
{ {
FillAreaRect(_contentRect, WHITE); FillAreaRect(_contentRect, WHITE);
@ -42,7 +42,7 @@ ListView::ListView(const irect *contentRect, const std::shared_ptr<vector<Item>>
_page = 1; _page = 1;
_shownPage = _page; _shownPage = _page;
auto i = _items->size(); auto i = _items.size();
auto z = 0; auto z = 0;
_entries.reserve(i); _entries.reserve(i);
@ -107,7 +107,7 @@ void ListView::drawFooter()
void ListView::drawEntry(int itemID) void ListView::drawEntry(int itemID)
{ {
FillAreaRect(_entries[itemID].getPosition(), WHITE); FillAreaRect(_entries[itemID].getPosition(), WHITE);
_entries[itemID].draw(_items->at(itemID), _entryFont, _entryFontBold, _entryFontHeight); _entries[itemID].draw(_items.at(itemID), _entryFont, _entryFontBold, _entryFontHeight);
} }
void ListView::drawEntries() void ListView::drawEntries()
@ -115,7 +115,7 @@ void ListView::drawEntries()
for (auto i = 0; i < _entries.size(); i++) for (auto i = 0; i < _entries.size(); i++)
{ {
if (_entries[i].getPage() == _shownPage) if (_entries[i].getPage() == _shownPage)
_entries[i].draw(_items->at(i), _entryFont, _entryFontBold, _entryFontHeight); _entries[i].draw(_items.at(i), _entryFont, _entryFontBold, _entryFontHeight);
} }
} }

View File

@ -29,7 +29,7 @@ public:
* @param ContentRect area of the screen where the list view is placed * @param ContentRect area of the screen where the list view is placed
* @param Items items that shall be shown in the listview * @param Items items that shall be shown in the listview
*/ */
ListView(const irect *contentRect, const std::shared_ptr<vector<Item>> items); ListView(const irect *contentRect, const vector<Item> items);
/** /**
* Destructor * Destructor
@ -75,7 +75,7 @@ private:
int _footerFontHeight; int _footerFontHeight;
int _entryFontHeight; int _entryFontHeight;
const irect *_contentRect; const irect *_contentRect;
const std::shared_ptr<vector<Item>> _items = nullptr; vector<Item> _items;
vector<ListViewEntry> _entries; vector<ListViewEntry> _entries;
ifont *_headerFont; ifont *_headerFont;
ifont *_footerFont; ifont *_footerFont;

View File

@ -22,11 +22,10 @@ using std::ofstream;
using std::string; using std::string;
//neccesary to use Dialog method //neccesary to use Dialog method
Nextcloud *Nextcloud::nextcloudStatic; std::unique_ptr<Nextcloud> Nextcloud::_nextcloudStatic;
Nextcloud::Nextcloud() Nextcloud::Nextcloud()
{ {
nextcloudStatic = this; _nextcloudStatic = std::unique_ptr<Nextcloud>(this);
if (iv_access(NEXTCLOUD_PATH.c_str(), W_OK) != 0) if (iv_access(NEXTCLOUD_PATH.c_str(), W_OK) != 0)
iv_mkdir(NEXTCLOUD_PATH.c_str(), 0777); iv_mkdir(NEXTCLOUD_PATH.c_str(), 0777);
@ -67,6 +66,31 @@ void Nextcloud::setStartFolder(const string &Path)
CloseConfig(nextcloudConfig); CloseConfig(nextcloudConfig);
} }
bool Nextcloud::setItems(const vector<Item> &tempItems)
{
if (tempItems.empty())
return false;
if (!_items.empty())
_items.clear();
_items = tempItems;
//resize item 1
string header = _items.at(0).getPath();
header = header.substr(0, header.find_last_of("/"));
header = header.substr(0, header.find_last_of("/") + 1);
_items.at(0).setPath(header);
_items.at(0).setTitle("...");
_items.at(0).setLastEditDate("");
if (_items.at(0).getPath().compare(NEXTCLOUD_ROOT_PATH) == 0)
_items.erase(_items.begin());
return true;
}
bool Nextcloud::login() bool Nextcloud::login()
{ {
string tempPath = getStartFolder(); string tempPath = getStartFolder();
@ -74,7 +98,7 @@ bool Nextcloud::login()
if (tempPath.empty()) if (tempPath.empty())
tempPath = NEXTCLOUD_ROOT_PATH + this->getUsername() + "/"; tempPath = NEXTCLOUD_ROOT_PATH + this->getUsername() + "/";
if (getDataStructure(tempPath, this->getUsername(), this->getPassword())) if (setItems(getDataStructure(tempPath)))
{ {
_loggedIn = true; _loggedIn = true;
return true; return true;
@ -87,7 +111,7 @@ bool Nextcloud::login(const string &Url, const string &Username, const string &P
{ {
_url = Url; _url = Url;
string tempPath = NEXTCLOUD_ROOT_PATH + Username + "/"; string tempPath = NEXTCLOUD_ROOT_PATH + Username + "/";
if (getDataStructure(tempPath, Username, Pass)) if (setItems(getDataStructure(tempPath, Username, Pass)))
{ {
if (iv_access(NEXTCLOUD_CONFIG_PATH.c_str(), W_OK) != 0) if (iv_access(NEXTCLOUD_CONFIG_PATH.c_str(), W_OK) != 0)
iv_buildpath(NEXTCLOUD_CONFIG_PATH.c_str()); iv_buildpath(NEXTCLOUD_CONFIG_PATH.c_str());
@ -112,14 +136,14 @@ void Nextcloud::logout(bool deleteFiles)
remove((NEXTCLOUD_CONFIG_PATH + ".back.").c_str()); remove((NEXTCLOUD_CONFIG_PATH + ".back.").c_str());
_url.clear(); _url.clear();
_items = nullptr; _items.clear();
_workOffline = false; _workOffline = false;
_loggedIn = false; _loggedIn = false;
} }
void Nextcloud::downloadItem(int itemID) void Nextcloud::downloadItem(int itemID)
{ {
Log::writeLog("started download of " + _items->at(itemID).getPath() + " to " + _items->at(itemID).getLocalPath()); Log::writeLog("started download of " + _items.at(itemID).getPath() + " to " + _items.at(itemID).getLocalPath());
if (!Util::connectToNetwork()) if (!Util::connectToNetwork())
{ {
@ -127,7 +151,7 @@ void Nextcloud::downloadItem(int itemID)
_workOffline = true; _workOffline = true;
} }
if (_items->at(itemID).getPath().empty()) if (_items.at(itemID).getPath().empty())
{ {
Message(ICON_ERROR, "Error", "Download path is not set, therefore cannot download the file.", 1200); Message(ICON_ERROR, "Error", "Download path is not set, therefore cannot download the file.", 1200);
return; return;
@ -143,9 +167,9 @@ void Nextcloud::downloadItem(int itemID)
string post = this->getUsername() + std::string(":") + this->getPassword(); string post = this->getUsername() + std::string(":") + this->getPassword();
FILE *fp; FILE *fp;
fp = iv_fopen(_items->at(itemID).getLocalPath().c_str(), "wb"); fp = iv_fopen(_items.at(itemID).getLocalPath().c_str(), "wb");
curl_easy_setopt(curl, CURLOPT_URL, (_url + _items->at(itemID).getPath()).c_str()); curl_easy_setopt(curl, CURLOPT_URL, (_url + _items.at(itemID).getPath()).c_str());
curl_easy_setopt(curl, CURLOPT_USERPWD, post.c_str()); curl_easy_setopt(curl, CURLOPT_USERPWD, post.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Util::writeData); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Util::writeData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
@ -165,8 +189,8 @@ void Nextcloud::downloadItem(int itemID)
switch (response_code) switch (response_code)
{ {
case 200: case 200:
Log::writeLog("finished download of " + _items->at(itemID).getPath() + " to " + _items->at(itemID).getLocalPath()); Log::writeLog("finished download of " + _items.at(itemID).getPath() + " to " + _items.at(itemID).getLocalPath());
_items->at(itemID).setState(FileState::ISYNCED); _items.at(itemID).setState(FileState::ISYNCED);
break; break;
case 401: case 401:
Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200); Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200);
@ -179,14 +203,47 @@ void Nextcloud::downloadItem(int itemID)
} }
} }
bool Nextcloud::getDataStructure(string &pathUrl) bool Nextcloud::downloadFolder(const vector<Item> &tempItems, int itemId)
{
//also has to look at the previous items?
//do not change items oxml or use temp here?
if (tempItems.at(itemId).getType() == Itemtype::IFOLDER)
{
//get the data structure under the folder that is requested --> overrides items object and therefore will fail!
//should return items vector?
string temp = tempItems.at(itemId).getPath();
vector<Item> tempItemsNew = getDataStructure(temp);
//this will be the new item list --> where to switch to when this process is over --> open the folder that has t be synced?
//get item id?
for (auto i = 0; i < tempItemsNew.size(); i++)
{
downloadFolder(tempItemsNew,itemId);
//overrides current item list and therefore nos possible!
// has to be read in again?
// call method again?
}
}
else
{
downloadItem(itemId);
}
return true;
}
vector<Item> Nextcloud::getDataStructure(string &pathUrl)
{ {
return getDataStructure(pathUrl, this->getUsername(), this->getPassword()); return getDataStructure(pathUrl, this->getUsername(), this->getPassword());
} }
bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, const string &Pass) vector<Item> Nextcloud::getDataStructure(const string &pathUrl, const string &Username, const string &Pass)
{ {
//could not connect to internet, therefore offline modus
if (_workOffline) if (_workOffline)
return getOfflineStructure(pathUrl); return getOfflineStructure(pathUrl);
@ -203,7 +260,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username,
if (Username.empty() || Pass.empty()) if (Username.empty() || Pass.empty())
{ {
Message(ICON_ERROR, "Error", "Username/password not set.", 1200); Message(ICON_ERROR, "Error", "Username/password not set.", 1200);
return false; return {};
} }
string readBuffer; string readBuffer;
@ -238,15 +295,15 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username,
string localPath = this->getLocalPath(pathUrl); string localPath = this->getLocalPath(pathUrl);
//create items_ //create items_
if (!readInXML(readBuffer)) vector<Item> tempItems = readInXML(readBuffer);
return false; if (tempItems.empty())
return {};
if (iv_access(localPath.c_str(), W_OK) != 0) if (iv_access(localPath.c_str(), W_OK) != 0)
{ {
//if the current folder does not exist locally, create it //if the current folder does not exist locally, create it
iv_buildpath(localPath.c_str()); iv_buildpath(localPath.c_str());
} }
else else
{ {
//get items from local path //get items from local path
@ -274,7 +331,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username,
} }
outFile.close(); outFile.close();
return true; return tempItems;
} }
case 401: case 401:
Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200); Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200);
@ -286,7 +343,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username,
} }
} }
} }
return false; return {};
} }
string Nextcloud::getUrl() string Nextcloud::getUrl()
@ -329,11 +386,11 @@ void Nextcloud::DialogHandlerStatic(int Button)
{ {
if (Button == 2) if (Button == 2)
{ {
nextcloudStatic->_workOffline = true; _nextcloudStatic->_workOffline = true;
} }
} }
bool Nextcloud::readInXML(string xml) vector<Item> Nextcloud::readInXML(string xml)
{ {
size_t begin; size_t begin;
size_t end; size_t end;
@ -347,32 +404,15 @@ bool Nextcloud::readInXML(string xml)
{ {
end = xml.find(endItem); end = xml.find(endItem);
tempItems.push_back(Item(xml.substr(begin, end))); tempItems.push_back(xml.substr(begin,end));
xml = xml.substr(end + endItem.length()); xml = xml.substr(end + endItem.length());
begin = xml.find(beginItem); begin = xml.find(beginItem);
} }
if (_items) return tempItems;
_items->clear();
_items = std::make_shared<vector<Item>>(std::move(tempItems));
if (_items->size() < 1)
return false;
//resize item 1
string header = _items->at(0).getPath();
header = header.substr(0, header.find_last_of("/"));
header = header.substr(0, header.find_last_of("/") + 1);
_items->at(0).setPath(header);
_items->at(0).setTitle("...");
_items->at(0).setLastEditDate("");
if (_items->at(0).getPath().compare(NEXTCLOUD_ROOT_PATH) == 0)
_items->erase(_items->begin());
return true;
} }
string Nextcloud::getLocalPath(string path) string Nextcloud::getLocalPath(string path)
@ -384,7 +424,7 @@ string Nextcloud::getLocalPath(string path)
return NEXTCLOUD_FILE_PATH + "/" + path; return NEXTCLOUD_FILE_PATH + "/" + path;
} }
bool Nextcloud::getOfflineStructure(const string &pathUrl) vector<Item> Nextcloud::getOfflineStructure(const string &pathUrl)
{ {
string localPath = this->getLocalPath(pathUrl) + NEXTCLOUD_STRUCTURE_EXTENSION; string localPath = this->getLocalPath(pathUrl) + NEXTCLOUD_STRUCTURE_EXTENSION;
if (iv_access(localPath.c_str(), W_OK) == 0) if (iv_access(localPath.c_str(), W_OK) == 0)
@ -393,10 +433,13 @@ bool Nextcloud::getOfflineStructure(const string &pathUrl)
std::stringstream buffer; std::stringstream buffer;
buffer << inFile.rdbuf(); buffer << inFile.rdbuf();
if (!readInXML(buffer.str())) vector<Item> tempItems = readInXML(buffer.str());
return false;
if (tempItems.empty())
return {};
getLocalFileStructure(this->getLocalPath(pathUrl)); getLocalFileStructure(this->getLocalPath(pathUrl));
return tempItems;
} }
else else
{ {
@ -411,8 +454,7 @@ bool Nextcloud::getOfflineStructure(const string &pathUrl)
Message(ICON_ERROR, "Error", "The selected structure is not available offline.", 1200); Message(ICON_ERROR, "Error", "The selected structure is not available offline.", 1200);
} }
} }
return {};
return false;
} }
void Nextcloud::getLocalFileStructure(const string &localPath) void Nextcloud::getLocalFileStructure(const string &localPath)
@ -441,10 +483,10 @@ void Nextcloud::getLocalFileStructure(const string &localPath)
continue; continue;
bool found = false; bool found = false;
for (auto i = 0; i < _items->size(); i++) for (auto i = 0; i < _items.size(); i++)
{ {
//TODO compare last edit local and in cloud and display to user //TODO compare last edit local and in cloud and display to user
if (_items->at(i).getLocalPath().compare(full_file_name) == 0) if (_items.at(i).getLocalPath().compare(full_file_name) == 0)
{ {
found = true; found = true;
break; break;
@ -452,7 +494,7 @@ void Nextcloud::getLocalFileStructure(const string &localPath)
} }
if (!found) if (!found)
{ {
_items->push_back(Item(full_file_name, FileState::ILOCAL)); _items.push_back(Item(full_file_name, FileState::ILOCAL));
} }
} }
closedir(dir); closedir(dir);

View File

@ -58,20 +58,27 @@ public:
*/ */
void downloadItem(int itemID); void downloadItem(int itemID);
/**
*
*
*/
bool downloadFolder(const vector<Item> &tempItems, int itemId);
/** /**
* gets the dataStructure of the given URL and writes its WEBDAV items to the items vector, reads Userdata from configfile * gets the dataStructure of the given URL and writes its WEBDAV items to the items vector, reads Userdata from configfile
* *
* @param pathUrl URL to get the dataStructure of * @param pathUrl URL to get the dataStructure of
* @return true - sucessfull, false - error * @return vector of items
*/ */
bool getDataStructure(string &pathUrl); vector<Item> getDataStructure(string &pathUrl);
void setURL(const string &Url); void setURL(const string &Url);
void setUsername(const string &Username); void setUsername(const string &Username);
void setPassword(const string &Pass); void setPassword(const string &Pass);
void setStartFolder(const string &Path); void setStartFolder(const string &Path);
std::shared_ptr<vector<Item>> getItems() const { return _items; }; vector<Item> getItems() const { return _items; };
bool isLoggedIn() const { return _loggedIn; }; bool isLoggedIn() const { return _loggedIn; };
bool isWorkOffline() const { return _workOffline; }; bool isWorkOffline() const { return _workOffline; };
void switchWorkOffline() { _workOffline = !_workOffline; }; void switchWorkOffline() { _workOffline = !_workOffline; };
@ -80,10 +87,14 @@ public:
void getLocalFileStructure(const string &localPath); void getLocalFileStructure(const string &localPath);
private:
static Nextcloud *nextcloudStatic;
std::shared_ptr<vector<Item>> _items = nullptr; bool setItems(const vector<Item> &tempItems);
private:
static std::unique_ptr<Nextcloud> _nextcloudStatic;
vector<Item> _items;
bool _loggedIn{false}; bool _loggedIn{false};
string _url; string _url;
bool _workOffline{false}; bool _workOffline{false};
@ -94,9 +105,9 @@ private:
* @param pathUrl URL to get the dataStructure of * @param pathUrl URL to get the dataStructure of
* @param Username the username of the Nextcloud instance * @param Username the username of the Nextcloud instance
* @param Pass the pass of the Nextcloud instance * @param Pass the pass of the Nextcloud instance
* @return true - sucessfull, false - error * @return vector of Items
*/ */
bool getDataStructure(const string &pathUrl, const string &Username, const string &Pass); vector<Item> getDataStructure(const string &pathUrl, const string &Username, const string &Pass);
string getUrl(); string getUrl();
string getUsername(); string getUsername();
@ -112,9 +123,9 @@ private:
*/ */
static void DialogHandlerStatic(int Button); static void DialogHandlerStatic(int Button);
bool readInXML(string xml); vector<Item> readInXML(string xml);
bool getOfflineStructure(const string &pathUrl); vector<Item> getOfflineStructure(const string &pathUrl);
}; };
#endif #endif