Skip to content

Commit

Permalink
Merge pull request #30 from RPJoshL/master
Browse files Browse the repository at this point in the history
Feature: hide files and folders
  • Loading branch information
JuanJakobo authored Oct 17, 2022
2 parents c88a867 + 381d668 commit 790fd6f
Show file tree
Hide file tree
Showing 19 changed files with 1,003 additions and 90 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ set(SOURCES ${CMAKE_SOURCE_DIR}/src/main.cpp
${CMAKE_SOURCE_DIR}/src/handler/contextMenu.cpp
${CMAKE_SOURCE_DIR}/src/handler/eventHandler.cpp
${CMAKE_SOURCE_DIR}/src/handler/mainMenu.cpp
${CMAKE_SOURCE_DIR}/src/handler/fileHandler.cpp
${CMAKE_SOURCE_DIR}/src/ui/listView.cpp
${CMAKE_SOURCE_DIR}/src/ui/listViewEntry.cpp
${CMAKE_SOURCE_DIR}/src/ui/webDAVView/webDAVView.cpp
${CMAKE_SOURCE_DIR}/src/ui/webDAVView/webDAVViewEntry.cpp
${CMAKE_SOURCE_DIR}/src/ui/loginView/loginView.cpp
${CMAKE_SOURCE_DIR}/src/ui/fileView/fileView.cpp
${CMAKE_SOURCE_DIR}/src/ui/fileView/fileViewEntry.cpp
${CMAKE_SOURCE_DIR}/src/ui/excludeFileView/excludeFileView.cpp
${CMAKE_SOURCE_DIR}/src/util/util.cpp
${CMAKE_SOURCE_DIR}/src/util/log.cpp
${CMAKE_SOURCE_DIR}/src/api/webDAV.cpp
Expand All @@ -78,10 +80,12 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/ui/webDAVView/
${CMAKE_SOURCE_DIR}/src/ui/fileView/
${CMAKE_SOURCE_DIR}/src/ui/loginView/
${CMAKE_SOURCE_DIR}/src/ui/excludeFileView/
${CMAKE_SOURCE_DIR}/src/api/
)

TARGET_LINK_LIBRARIES (Nextcloud.app PRIVATE inkview freetype curl sqlite3 stdc++fs)
target_compile_definitions(Nextcloud.app PRIVATE DBVERSION=2 PROGRAMVERSION="1.02")

INSTALL (TARGETS Nextcloud.app)

17 changes: 14 additions & 3 deletions src/api/fileBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "fileBrowser.h"
#include "inkview.h"
#include "fileHandler.h"
#include "log.h"

#include <string>
#include <experimental/filesystem>
Expand All @@ -18,6 +20,7 @@ using std::vector;

namespace fs = std::experimental::filesystem;

std::shared_ptr<FileHandler> FileBrowser::_fileHandler = std::shared_ptr<FileHandler>(new FileHandler());
std::vector<FileItem> FileBrowser::getFileStructure(const std::string &path, const bool includeFiles, const bool includeHeader)
{
string localPath = path;
Expand All @@ -38,6 +41,7 @@ std::vector<FileItem> FileBrowser::getFileStructure(const std::string &path, con
items.push_back(temp);
}

const int storageLocationLength = _fileHandler->getStorageLocation().length();
if (iv_access(localPath.c_str(), R_OK) == 0)
{
for (const auto &entry : fs::directory_iterator(localPath))
Expand All @@ -46,20 +50,27 @@ std::vector<FileItem> FileBrowser::getFileStructure(const std::string &path, con
auto time = std::chrono::system_clock::to_time_t(fs::last_write_time(entry));
temp.lastEditDate = *gmtime(&time);


string directoryPath = temp.path;
if (directoryPath.length() > storageLocationLength + 1) {
directoryPath = directoryPath.substr(storageLocationLength + 1);
}
if(is_directory(entry))
{
temp.path = entry.path();
temp.name = temp.path.substr(temp.path.find_last_of('/') + 1, temp.path.length());
temp.type = Type::FFOLDER;
items.push_back(temp);
if (!_fileHandler->excludeFolder(directoryPath + "/")) {
items.push_back(temp);
}
}
else if (includeFiles)
{
temp.path = entry.path();
temp.name = temp.path.substr(temp.path.find_last_of('/') + 1, temp.path.length());
temp.type = Type::FFILE;
items.push_back(temp);
if (!_fileHandler->excludeFolder(directoryPath.substr(0, directoryPath.length())) || !_fileHandler->excludeFile(temp.name)) {
items.push_back(temp);
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/api/fileBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
#define FILEBROWSER

#include "fileModel.h"
#include "fileHandler.h"

#include <string>
#include <vector>
#include <memory>

class FileBrowser
{
Expand All @@ -23,5 +25,7 @@ class FileBrowser
private:
FileBrowser(){};

static std::shared_ptr<FileHandler> _fileHandler;

};
#endif
161 changes: 158 additions & 3 deletions src/api/sqliteConnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,101 @@
#include "sqlite3.h"
#include "log.h"
#include "util.h"
#include "fileHandler.h"
#include "webDAV.h"

#include <string>
#include <vector>
#include <regex>

using std::string;

SqliteConnector::SqliteConnector(const string &DBpath) : _dbpath(DBpath)
{
_fileHandler = std::shared_ptr<FileHandler>(new FileHandler());

// check if migration has to be run
int currentVersion = getDbVersion();
if (currentVersion != DBVERSION) {
runMigration(currentVersion);
}
}

SqliteConnector::~SqliteConnector()
{
sqlite3_close(_db);
_fileHandler.reset();
Log::writeInfoLog("closed DB");
}

void SqliteConnector::runMigration(int currentVersion)
{
open();

char* log;
sprintf(log, "Running migration from db version %i to %i (Program version %s)", currentVersion, DBVERSION, PROGRAMVERSION);
Log::writeInfoLog(log);

// currently there are no migrations

// updating to current version
int rs;
sqlite3_stmt *stmt = 0;

rs = sqlite3_prepare_v2(_db, "INSERT INTO 'version' (dbversion) VALUES (?)", -1, &stmt, 0);
rs = sqlite3_bind_int(stmt, 1, DBVERSION);

rs = sqlite3_step(stmt);
if (rs != SQLITE_DONE) {
// this is critical
Log::writeErrorLog(std::string("error inserting into version") + sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")");
}

sqlite3_finalize(stmt);
sqlite3_close(_db);
}

int SqliteConnector::getDbVersion()
{
open();

int rs;
sqlite3_stmt *stmt = 0;

int version;
rs = sqlite3_prepare_v2(_db, "SELECT MAX(dbversion) FROM 'version'", -1, &stmt, 0);
while (sqlite3_step(stmt) == SQLITE_ROW)
{
version = sqlite3_column_int(stmt, 0);
}

if (version != 0)
{
sqlite3_finalize(stmt);
sqlite3_close(_db);
return version;
} else {
// this is probably the first start -> the version is up to date and insert the current version
rs = sqlite3_prepare_v2(_db, "INSERT INTO 'version' (dbversion) VALUES (?)", -1, &stmt, 0);
rs = sqlite3_bind_int(stmt, 1, DBVERSION);

rs = sqlite3_step(stmt);
if (rs != SQLITE_DONE) {
Log::writeErrorLog(std::string("error inserting into version") + sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")");
}
rs = sqlite3_clear_bindings(stmt);
rs = sqlite3_reset(stmt);

// for compatibility alter the table because at this point db migrations doesn't exist
rs = sqlite3_exec(_db, "ALTER TABLE metadata ADD hide INT DEFAULT 0 NOT NULL", NULL, 0, NULL);

sqlite3_finalize(stmt);
sqlite3_close(_db);

return DBVERSION;
}
}

bool SqliteConnector::open()
{
int rs;
Expand All @@ -38,7 +118,8 @@ bool SqliteConnector::open()
return false;
}

rs = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS metadata (title VARCHAR, localPath VARCHAR, size VARCHAR, fileType VARCHAR, lasteditDate VARCHAR, type INT, state INT, etag VARCHAR, path VARCHAR PRIMARY KEY, parentPath VARCHAR)", NULL, 0, NULL);
rs = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS metadata (title VARCHAR, localPath VARCHAR, size VARCHAR, fileType VARCHAR, lasteditDate VARCHAR, type INT, state INT, etag VARCHAR, path VARCHAR PRIMARY KEY, parentPath VARCHAR, hide INT DEFAULT 0 NOT NULL)", NULL, 0, NULL);
rs = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS version (dbversion INT)", NULL, 0, NULL);

return true;
}
Expand Down Expand Up @@ -120,10 +201,15 @@ std::vector<WebDAVItem> SqliteConnector::getItemsChildren(const string &parentPa
sqlite3_stmt *stmt = 0;
std::vector<WebDAVItem> items;

rs = sqlite3_prepare_v2(_db, "SELECT title, localPath, path, size, etag, fileType, lastEditDate, type, state FROM 'metadata' WHERE path=? OR parentPath=? ORDER BY parentPath;", -1, &stmt, 0);
rs = sqlite3_prepare_v2(
_db,
"SELECT title, localPath, path, size, etag, fileType, lastEditDate, type, state, hide FROM 'metadata' WHERE (path=? OR parentPath=?) AND hide <> 2 ORDER BY parentPath;",
-1, &stmt, 0
);
rs = sqlite3_bind_text(stmt, 1, parentPath.c_str(), parentPath.length(), NULL);
rs = sqlite3_bind_text(stmt, 2, parentPath.c_str(), parentPath.length(), NULL);

const string storageLocation = NEXTCLOUD_ROOT_PATH + _fileHandler->getStorageUsername() + "/";
while (sqlite3_step(stmt) == SQLITE_ROW)
{
WebDAVItem temp;
Expand All @@ -137,21 +223,89 @@ std::vector<WebDAVItem> SqliteConnector::getItemsChildren(const string &parentPa
temp.lastEditDate = Util::webDAVStringToTm(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 6)));
temp.type = static_cast<Itemtype>(sqlite3_column_int(stmt,7));
temp.state = static_cast<FileState>(sqlite3_column_int(stmt,8));
temp.hide = static_cast<HideState>(sqlite3_column_int(stmt,9));

if (iv_access(temp.localPath.c_str(), W_OK) != 0)
{
if (temp.type == Itemtype::IFILE)
temp.state = FileState::ICLOUD;
}

if (temp.hide == HideState::INOTDEFINED) {
temp.hide = _fileHandler->getHideState(temp.type, storageLocation, temp.path, temp.title);
}
items.push_back(temp);
}

sqlite3_finalize(stmt);
sqlite3_close(_db);

return items;
}

void SqliteConnector::deleteChild(const string &path, const string &title)
{
open();
int rs;
sqlite3_stmt *stmt = 0;
rs = sqlite3_prepare_v2(_db, "DELETE FROM 'metadata' WHERE path = ? AND title = ?", -1, &stmt, 0);
rs = sqlite3_bind_text(stmt, 1, path.c_str(), path.length(), NULL);
rs = sqlite3_bind_text(stmt, 1, title.c_str(), title.length(), NULL);

rs = sqlite3_step(stmt);
if (rs != SQLITE_DONE)
{
Log::writeErrorLog(std::string("An error ocurred trying to delete the item ") + sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")");
}
rs = sqlite3_clear_bindings(stmt);
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()
{
open();
int rs;
sqlite3_stmt *stmt = 0;

rs = sqlite3_prepare_v2(_db, "UPDATE 'metadata' SET hide=0", -1, &stmt, 0);
rs = sqlite3_step(stmt);

if (rs != SQLITE_DONE)
{
Log::writeErrorLog(sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")");
}
rs = sqlite3_clear_bindings(stmt);
rs = sqlite3_reset(stmt);

sqlite3_finalize(stmt);
sqlite3_close(_db);

return true;
}

void SqliteConnector::deleteChildren(const string &parentPath)
{
//TODO missing the onces where parentPath is one folder deeper and also destroyed
Expand Down Expand Up @@ -185,7 +339,7 @@ bool SqliteConnector::saveItemsChildren(const std::vector<WebDAVItem> &items)

for (auto item : items)
{
rs = sqlite3_prepare_v2(_db, "INSERT INTO 'metadata' (title, localPath, path, size, parentPath, etag, fileType, lastEditDate, type, state) VALUES (?,?,?,?,?,?,?,?,?,?);", -1, &stmt, 0);
rs = sqlite3_prepare_v2(_db, "INSERT INTO 'metadata' (title, localPath, path, size, parentPath, etag, fileType, lastEditDate, type, state, hide) VALUES (?,?,?,?,?,?,?,?,?,?,?);", -1, &stmt, 0);
rs = sqlite3_exec(_db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
rs = sqlite3_bind_text(stmt, 1, item.title.c_str(), item.title.length(), NULL);
rs = sqlite3_bind_text(stmt, 2, item.localPath.c_str(), item.localPath.length(), NULL);
Expand All @@ -198,6 +352,7 @@ bool SqliteConnector::saveItemsChildren(const std::vector<WebDAVItem> &items)
rs = sqlite3_bind_text(stmt, 8, lastEditDateString.c_str(), lastEditDateString.length(), NULL);
rs = sqlite3_bind_int(stmt, 9, item.type);
rs = sqlite3_bind_int(stmt, 10, item.state);
rs = sqlite3_bind_int(stmt, 11, item.hide);

rs = sqlite3_step(stmt);
if (rs == SQLITE_CONSTRAINT)
Expand Down
15 changes: 15 additions & 0 deletions src/api/sqliteConnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@

#include "webDAVModel.h"
#include "sqlite3.h"
#include "fileHandler.h"

#include <string>
#include <vector>

#include <memory>

class SqliteConnector
{
public:
Expand All @@ -28,6 +31,10 @@ class SqliteConnector

bool open();

int getDbVersion();

void runMigration(int currentVersion);

std::string getEtag(const std::string &path);

FileState getState(const std::string &path);
Expand All @@ -38,11 +45,19 @@ class SqliteConnector

void deleteChildren(const std::string &parentPath);

void deleteChild(const std::string &path, const std::string &title);

void deleteItemsNotBeginsWith(std::string beginPath);

bool resetHideState();

bool saveItemsChildren(const std::vector<WebDAVItem> &children);

private:
std::string _dbpath;
sqlite3 *_db;

std::shared_ptr<FileHandler> _fileHandler;
};

#endif
Loading

0 comments on commit 790fd6f

Please sign in to comment.