Add option to set the default start folder when opening the app
parent
2f84fec1a9
commit
75dd96222e
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
|
||||
using std::string;
|
||||
|
||||
SqliteConnector::SqliteConnector(const string &DBpath) : _dbpath(DBpath)
|
||||
|
@ -259,6 +261,28 @@ void SqliteConnector::deleteChild(const string &path, const string &title)
|
|||
rs = sqlite3_reset(stmt);
|
||||
|
||||
}
|
||||
void SqliteConnector::deleteItemsNotBeginsWith(string beginPath)
|
||||
{
|
||||
open();
|
||||
|
||||
// escape characters
|
||||
beginPath = std::regex_replace(beginPath, std::regex("%"), "#%");
|
||||
beginPath = std::regex_replace(beginPath, std::regex("_"), "#_");
|
||||
beginPath = beginPath + "%";
|
||||
|
||||
int rs;
|
||||
sqlite3_stmt *stmt = 0;
|
||||
rs = sqlite3_prepare_v2(_db, "DELETE FROM 'metadata' WHERE path NOT LIKE ? ESCAPE '#'", -1, &stmt, 0);
|
||||
rs = sqlite3_bind_text(stmt, 1, beginPath.c_str(), beginPath.length(), NULL);
|
||||
|
||||
rs = sqlite3_step(stmt);
|
||||
if (rs != SQLITE_DONE)
|
||||
{
|
||||
Log::writeErrorLog(std::string("An error ocurred trying to delete the items that begins with " + beginPath) + sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")");
|
||||
}
|
||||
rs = sqlite3_clear_bindings(stmt);
|
||||
rs = sqlite3_reset(stmt);
|
||||
}
|
||||
|
||||
bool SqliteConnector::resetHideState()
|
||||
{
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
|
||||
void deleteChild(const std::string &path, const std::string &title);
|
||||
|
||||
void deleteItemsNotBeginsWith(std::string beginPath);
|
||||
|
||||
bool resetHideState();
|
||||
|
||||
bool saveItemsChildren(const std::vector<WebDAVItem> &children);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <regex>
|
||||
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
|
@ -27,6 +28,20 @@ using std::vector;
|
|||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
std::string WebDAV::getRootPath(bool encode) {
|
||||
string rootPath = Util::getConfig<std::string>("ex_relativeRootPath", "/");
|
||||
if (rootPath == "")
|
||||
rootPath += "/";
|
||||
|
||||
string rtc = NEXTCLOUD_ROOT_PATH + Util::getConfig<std::string>("UUID", "") + rootPath;
|
||||
if (encode) {
|
||||
Util::encodeUrl(rtc);
|
||||
rtc = std::regex_replace(rtc, std::regex("%2F"), "/");
|
||||
}
|
||||
|
||||
return rtc;
|
||||
}
|
||||
|
||||
WebDAV::WebDAV()
|
||||
{
|
||||
if (iv_access(NEXTCLOUD_PATH.c_str(), W_OK) != 0)
|
||||
|
@ -184,7 +199,7 @@ vector<WebDAVItem> WebDAV::getDataStructure(const string &pathUrl)
|
|||
tempItem.title = tempItem.title.substr(tempItem.title.find_last_of("/") + 1, tempItem.title.length());
|
||||
Util::decodeUrl(tempItem.title);
|
||||
|
||||
string &pathDecoded = tempItem.path;
|
||||
string pathDecoded = tempItem.path;
|
||||
Util::decodeUrl(pathDecoded);
|
||||
tempItem.hide = _fileHandler->getHideState(tempItem.type, prefix,(pathDecoded), tempItem.title);
|
||||
|
||||
|
@ -233,6 +248,7 @@ string WebDAV::propfind(const string &pathUrl)
|
|||
string readBuffer;
|
||||
CURLcode res;
|
||||
CURL *curl = curl_easy_init();
|
||||
Log::writeInfoLog("Path: " + pathUrl);
|
||||
|
||||
if (curl)
|
||||
{
|
||||
|
@ -274,7 +290,33 @@ string WebDAV::propfind(const string &pathUrl)
|
|||
switch (response_code)
|
||||
{
|
||||
case 404:
|
||||
if (getRootPath().compare( NEXTCLOUD_ROOT_PATH + Util::getConfig<std::string>("uuid", "")) != 0) {
|
||||
if (propfind(NEXTCLOUD_ROOT_PATH + Util::getConfig<std::string>("UUID", "")) != "") {
|
||||
// Own root path defined
|
||||
string output;
|
||||
int dialogResult = DialogSynchro(
|
||||
ICON_ERROR,
|
||||
"Action",
|
||||
output.append("The specified start folder does not seem to exist:\n").append(Util::getConfig<std::string>("ex_relativeRootPath", "/")).append("\n\nWhat would you like to do?").c_str(),
|
||||
"Reset start folder", "Close App", NULL
|
||||
);
|
||||
switch (dialogResult)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Util::accessConfig<string>(Action::IWriteString, "ex_relativeRootPath", "");
|
||||
return propfind(NEXTCLOUD_ROOT_PATH + Util::getConfig<std::string>("UUID", ""));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
CloseApp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Message(ICON_ERROR, "Error", "The URL seems to be incorrect. You can look up the WebDav URL in the settings of the files webapp. ", 4000);
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
Message(ICON_ERROR, "Error", "Username/password incorrect.", 4000);
|
||||
|
|
|
@ -38,6 +38,12 @@ class WebDAV
|
|||
|
||||
std::vector<WebDAVItem> getDataStructure(const std::string &pathUrl);
|
||||
|
||||
/**
|
||||
* Returns the root path of the nextcloud server
|
||||
* (e.g. /remote.php/dav/files/userName/startFolder/)
|
||||
*/
|
||||
static std::string getRootPath(bool encode = false);
|
||||
|
||||
/**
|
||||
* gets the dataStructure of the given URL and writes its WEBDAV items to the items vector
|
||||
*
|
||||
|
|
|
@ -49,7 +49,7 @@ EventHandler::EventHandler()
|
|||
iv_mkdir(Util::accessConfig<string>(Action::IReadString, "storageLocation",{}).c_str(), 0777);
|
||||
|
||||
std::vector<WebDAVItem> currentWebDAVItems;
|
||||
string path = NEXTCLOUD_ROOT_PATH + Util::accessConfig<string>(Action::IReadString,"UUID",{}) + '/';
|
||||
string path = WebDAV::getRootPath(true);
|
||||
|
||||
currentWebDAVItems = _webDAV.getDataStructure(path);
|
||||
_menu = std::unique_ptr<MainMenu>(new MainMenu("Nextcloud"));
|
||||
|
@ -234,7 +234,7 @@ void EventHandler::mainMenuHandler(const int index)
|
|||
else
|
||||
{
|
||||
Util::accessConfig<string>(Action::IWriteString, "storageLocation", _currentPath);
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(NEXTCLOUD_ROOT_PATH + Util::accessConfig<string>(Action::IReadString,"UUID",{}) + '/');
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(WebDAV::getRootPath(true));
|
||||
if (currentWebDAVItems.empty())
|
||||
{
|
||||
Message(ICON_ERROR, "Error", "Failed to get items. Please try again.", 1000);
|
||||
|
@ -388,8 +388,14 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
|
|||
Util::accessConfig<string>(Action::IWriteString, "ex_extensionList", _excludeFileView->getExtensionList());
|
||||
Util::accessConfig<string>(Action::IWriteString, "ex_pattern",_excludeFileView->getRegex());
|
||||
Util::accessConfig<string>(Action::IWriteString, "ex_folderPattern",_excludeFileView->getFolderRegex());
|
||||
Util::accessConfig<string>(Action::IWriteString, "ex_relativeRootPath", _excludeFileView->getStartFolder());
|
||||
Util::accessConfig<int>(Action::IWriteInt, "ex_invertMatch", _excludeFileView->getInvertMatch());
|
||||
|
||||
_sqllite.resetHideState();
|
||||
if (_excludeFileView->getStartFolder() != "")
|
||||
{
|
||||
_sqllite.deleteItemsNotBeginsWith(WebDAV::getRootPath(true));
|
||||
}
|
||||
|
||||
_excludeFileView.reset();
|
||||
ShowHourglassForce();
|
||||
|
@ -399,7 +405,7 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
|
|||
vector<FileItem> currentFolder = FileBrowser::getFileStructure(_currentPath,false,true);
|
||||
_fileView.reset(new FileView(_menu->getContentRect(), currentFolder,1));
|
||||
} else {
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(NEXTCLOUD_ROOT_PATH + Util::accessConfig<string>(Action::IReadString,"UUID",{}) + '/');
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(WebDAV::getRootPath(true));
|
||||
updateItems(currentWebDAVItems);
|
||||
drawWebDAVItems(currentWebDAVItems);
|
||||
}
|
||||
|
@ -413,7 +419,7 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2)
|
|||
vector<FileItem> currentFolder = FileBrowser::getFileStructure(_currentPath,false,true);
|
||||
_fileView.reset(new FileView(_menu->getContentRect(), currentFolder,1));
|
||||
} else {
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(NEXTCLOUD_ROOT_PATH + Util::accessConfig<string>(Action::IReadString,"UUID",{}) + '/');
|
||||
std::vector<WebDAVItem> currentWebDAVItems = _webDAV.getDataStructure(WebDAV::getRootPath(true));
|
||||
updateItems(currentWebDAVItems);
|
||||
drawWebDAVItems(currentWebDAVItems);
|
||||
}
|
||||
|
@ -509,7 +515,6 @@ void EventHandler::openItem()
|
|||
|
||||
void EventHandler::openFolder()
|
||||
{
|
||||
|
||||
std::vector<WebDAVItem> currentWebDAVItems;
|
||||
|
||||
switch ((_webDAVView->getCurrentEntry().state == FileState::ILOCAL) ? FileState::ILOCAL : _sqllite.getState(_webDAVView->getCurrentEntry().path))
|
||||
|
|
|
@ -55,7 +55,7 @@ private:
|
|||
char *_logout = strdup("Logout");
|
||||
char *_chooseFolder = strdup("Create here");
|
||||
char *_sortBy = strdup("Order items by");
|
||||
char *_excludeFiles = strdup("Exclude and hide files");
|
||||
char *_excludeFiles = strdup("Exclude and hide items");
|
||||
char *_info = strdup("Info");
|
||||
char *_exit = strdup("Close App");
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ ExcludeFileView::ExcludeFileView(const irect &contentRect): _contentRect(content
|
|||
_extensionList = Util::getConfig<string>("ex_extensionList", "");
|
||||
_regex = Util::getConfig<string>("ex_pattern", "");
|
||||
_folderRegex = Util::getConfig<string>("ex_folderPattern", "");
|
||||
_startFolder = Util::getConfig<string>("ex_relativeRootPath", "");
|
||||
_invertMatch = Util::getConfig<int>("ex_invertMatch",0);
|
||||
|
||||
int contentHeight = contentRect.h / 2;
|
||||
|
@ -54,20 +55,25 @@ ExcludeFileView::ExcludeFileView(const irect &contentRect): _contentRect(content
|
|||
DrawString(_folderRegexButton.x, _folderRegexButton.y, _folderRegex.c_str());
|
||||
DrawRect(_folderRegexButton.x - 1, _folderRegexButton.y - 1, _folderRegexButton.w + 2, _folderRegexButton.h + 2, BLACK);
|
||||
|
||||
_invertMatchButton = iRect(_contentRect.w - 2 * checkBoxWidth, beginY + 6 * contents, checkBoxWidth, contents, ALIGN_CENTER);
|
||||
_startFolderButton = iRect(beginX, beginY + 6 * contents, contentWidth, contents, ALIGN_CENTER);
|
||||
DrawTextRect(_startFolderButton.x, _startFolderButton.y - _fontHeight - _fontHeight/3, _startFolderButton.w, _startFolderButton.h, "Start folder:", ALIGN_LEFT);
|
||||
DrawString(_startFolderButton.x, _startFolderButton.y, _startFolder.c_str());
|
||||
DrawRect(_startFolderButton.x - 1, _startFolderButton.y - 1, _startFolderButton.w + 2, _startFolderButton.h + 2, BLACK);
|
||||
|
||||
_invertMatchButton = iRect(_contentRect.w - 2 * checkBoxWidth, beginY + 8 * contents, checkBoxWidth, contents, ALIGN_CENTER);
|
||||
DrawTextRect(beginX, _invertMatchButton.y, contentWidth, _invertMatchButton.h, "Only include matching:", ALIGN_LEFT);
|
||||
DrawRect(_invertMatchButton.x - 1, _invertMatchButton.y - 1, _invertMatchButton.w + 2, _invertMatchButton.h + 2, BLACK);
|
||||
if (_invertMatch) {
|
||||
FillArea(_invertMatchButton.x - 1, _invertMatchButton.y - 1, _invertMatchButton.w + 2, _invertMatchButton.h + 2, BLACK);
|
||||
}
|
||||
|
||||
_saveButton = iRect(beginX, beginY + 8 * contents, contentWidth / 2 - 20, contents, ALIGN_CENTER);
|
||||
_saveButton = iRect(beginX, beginY + 10 * contents, contentWidth / 2 - 20, contents, ALIGN_CENTER);
|
||||
FillAreaRect(&_saveButton, BLACK);
|
||||
SetFont(_font, WHITE);
|
||||
DrawTextRect2(&_saveButton, "Save");
|
||||
PartialUpdate(_contentRect.x, _contentRect.y, _contentRect.w, _contentRect.h);
|
||||
|
||||
_cancelButton = iRect(beginX + contentWidth / 2, beginY + 8 * contents, contentWidth / 2 - 20, contents, ALIGN_CENTER);
|
||||
_cancelButton = iRect(beginX + contentWidth / 2, beginY + 10 * contents, contentWidth / 2 - 20, contents, ALIGN_CENTER);
|
||||
FillAreaRect(&_cancelButton, BLACK);
|
||||
SetFont(_font, WHITE);
|
||||
DrawTextRect2(&_cancelButton, "Cancel");
|
||||
|
@ -111,6 +117,15 @@ int ExcludeFileView::excludeClicked(int x, int y)
|
|||
OpenKeyboard("/root/.*/test/", &_temp[0], EXCLUDE_FILE_KEYBOARD_STRING_LENGHT, KBD_NORMAL, &keyboardHandlerStatic);
|
||||
return 1;
|
||||
}
|
||||
else if (IsInRect(x, y, &_startFolderButton))
|
||||
{
|
||||
_target = ExcludeFileKeyboardTarget::ISTARTFOLDER;
|
||||
if (!_startFolder.empty())
|
||||
_temp = _startFolder;
|
||||
_temp.resize(EXCLUDE_FILE_KEYBOARD_STRING_LENGHT);
|
||||
OpenKeyboard("/MyBooks/", &_temp[0], EXCLUDE_FILE_KEYBOARD_STRING_LENGHT, KBD_NORMAL, &keyboardHandlerStatic);
|
||||
return 1;
|
||||
}
|
||||
else if (IsInRect(x, y, &_invertMatchButton))
|
||||
{
|
||||
_invertMatch = !_invertMatch;
|
||||
|
@ -198,4 +213,18 @@ void ExcludeFileView::keyboardHandler(char *text)
|
|||
FillAreaRect(&_folderRegexButton, WHITE);
|
||||
DrawTextRect2(&_folderRegexButton, s.c_str());
|
||||
}
|
||||
else if (_target == ExcludeFileKeyboardTarget::ISTARTFOLDER)
|
||||
{
|
||||
_startFolder = s.c_str();
|
||||
if (_startFolder.length() > 1 && _startFolder != "/") {
|
||||
if (_startFolder.substr(0, 1) != "/") {
|
||||
_startFolder = "/" + _startFolder;
|
||||
}
|
||||
if (_startFolder.substr(_startFolder.length() - 1) != "/") {
|
||||
_startFolder = _startFolder + "/";
|
||||
}
|
||||
}
|
||||
FillAreaRect(&_startFolderButton, WHITE);
|
||||
DrawTextRect2(&_startFolderButton, _startFolder.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ enum class ExcludeFileKeyboardTarget
|
|||
{
|
||||
IEXTENSIONS,
|
||||
IREGEX,
|
||||
IFOLDERREGEX
|
||||
IFOLDERREGEX,
|
||||
ISTARTFOLDER,
|
||||
};
|
||||
|
||||
const int EXCLUDE_FILE_KEYBOARD_STRING_LENGHT = 90;
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
std::string getExtensionList() { return _extensionList; };
|
||||
std::string getRegex() { return _regex; };
|
||||
std::string getFolderRegex() { return _folderRegex; };
|
||||
std::string getStartFolder() { return _startFolder; };
|
||||
int getInvertMatch() { return _invertMatch; };
|
||||
|
||||
private:
|
||||
|
@ -64,10 +66,12 @@ private:
|
|||
irect _regexButton;
|
||||
irect _invertMatchButton;
|
||||
irect _folderRegexButton;
|
||||
irect _startFolderButton;
|
||||
ExcludeFileKeyboardTarget _target;
|
||||
std::string _extensionList;
|
||||
std::string _regex;
|
||||
std::string _folderRegex;
|
||||
std::string _startFolder;
|
||||
bool _invertMatch = false;
|
||||
std::string _temp;
|
||||
|
||||
|
|
|
@ -41,7 +41,9 @@ WebDAVView::WebDAVView(const irect &contentRect, vector<WebDAVItem> &itemsUnfilt
|
|||
|
||||
std::vector<WebDAVItem>::iterator begin;
|
||||
|
||||
if (items.at(0).path.compare(NEXTCLOUD_ROOT_PATH) == 0)
|
||||
string rootPath = WebDAV::getRootPath(false);
|
||||
string parentRootPath = rootPath.substr(0, rootPath.substr(0, rootPath.length() - 1).find_last_of("/") + 1);
|
||||
if (items.at(0).path.compare(parentRootPath) == 0)
|
||||
{
|
||||
items.erase(items.begin());
|
||||
begin = items.begin();
|
||||
|
|
|
@ -100,6 +100,18 @@ void Util::decodeUrl(string &text)
|
|||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
void Util::encodeUrl(string &text)
|
||||
{
|
||||
char *buffer;
|
||||
CURL *curl = curl_easy_init();
|
||||
|
||||
buffer = curl_easy_escape(curl, text.c_str(), 0);
|
||||
text = buffer;
|
||||
|
||||
curl_free(buffer);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
void kill_child(int sig)
|
||||
{
|
||||
//SIGKILL
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "log.h"
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
enum class Action
|
||||
{
|
||||
IWriteSecret,
|
||||
|
@ -25,7 +27,7 @@ enum class Action
|
|||
IReadInt
|
||||
};
|
||||
|
||||
const std::string CONFIG_PATH = CONFIG_FOLDER + "/nextcloud.cfg";
|
||||
const std::string CONFIG_PATH = "/mnt/ext1/system/config/nextcloud/nextcloud.cfg";
|
||||
|
||||
class Util
|
||||
{
|
||||
|
@ -155,6 +157,13 @@ public:
|
|||
*/
|
||||
static void decodeUrl(std::string &text);
|
||||
|
||||
/**
|
||||
* Encodes an URL
|
||||
*
|
||||
* @param text text that shall be converted
|
||||
*/
|
||||
static void encodeUrl(std::string &text);
|
||||
|
||||
/**
|
||||
* Updates the library of the Pocketbook
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue